связывание элементов str из списка в список кортежей - PullRequest
0 голосов
/ 15 января 2019

У меня есть следующий список:

lines
['line_North_Mid', 'line_South_Mid',
 'line_North_South', 'line_Mid_South',
 'line_South_North','line_Mid_North' ]

Я бы хотел объединить их в список кортежей по именам:

tuple_list
[('line_Mid_North', 'line_North_Mid'),
 ('line_North_South', 'line_South_North'),
 ('line_Mid_South', 'line_South_Mid')]

Я подумал, что, возможно, мне удастся найти строку в элементах lines, но она не будет эффективной. Есть ли лучший способ заказать элементы lines таким образом, чтобы они выглядели как tuple_list

Критерии очистки:

Если оба элемента имеют одинаковое имя_области: ('North', 'Mid', 'South')

Например: 'line_North_Mid' должен сочетаться с 'line_Mid_North'

Ответы [ 4 ]

0 голосов
/ 15 января 2019

Я полагаю, у вас есть функция, которая возвращает тот же ключ для строки, которая должна быть вместе (ключ группировки).

def key(s):
    # ignore first part and sort other 2 parts, so they will always be in same order
    _, part_1, part_2 = s.split('_')
    return tuple(sorted([part_1, part_2]))

Вы должны использовать какой-либо метод группировки; Я использовал defaultdict например:

import collections

lines = [
    'line_North_Mid', 'line_South_Mid',
    'line_North_South', 'line_Mid_South',
    'line_South_North','line_Mid_North',
]

dd = collections.defaultdict(list)
for s in lines:
    dd[key(s)].append(s)     # those with same key get grouped

print(list(tuple(v) for v in dd.values()))
# [
#     ('line_North_Mid', 'line_Mid_North'),
#     ('line_South_Mid', 'line_Mid_South'),
#     ('line_North_South', 'line_South_North'),
# ]
0 голосов
/ 15 января 2019

Решение, не зависящее от порядка O ( n ), возможно с использованием collections.defaultdict. Идея состоит в том, чтобы использовать в качестве наших словарных ключей последние 2 компонента ваших строк, разделенных '_', добавляя значения из вашего входного списка. Затем извлеките значения и преобразуйте их в список кортежей.

from collections import defaultdict

L = ['line_North_Mid', 'line_South_Mid',
     'line_North_South', 'line_Mid_South',
     'line_South_North', 'line_Mid_North']

dd = defaultdict(list)
for item in L:
    dd[frozenset(item.rsplit('_', maxsplit=2)[1:])].append(item)

res = list(map(tuple, dd.values()))

# [('line_North_Mid', 'line_Mid_North'),
#  ('line_South_Mid', 'line_Mid_South'),
#  ('line_North_South', 'line_South_North')]
0 голосов
/ 15 января 2019

Попробуйте это:

from itertools import combinations

tuple_list = [i for i in combinations(lines,2) if i[0].split('_')[1] == i[1].split('_')[2] and i[0].split('_')[2] == i[1].split('_')[1]]

или я думаю, что это лучше:

[i for i in combinations(lines,2) if i[0].split('_')[1:] == i[1].split('_')[1:][::-1]]
0 голосов
/ 15 января 2019

Вы можете использовать следующее понимание списка:

lines = ['line_Mid_North', 'line_North_Mid',
         'line_North_South', 'line_South_North',
         'line_Mid_South', 'line_South_Mid']

[(j,i) for i in lines for j in lines if j not in i 
       if set(j.split('_')[1:]) < set(i.split('_'))][::2]

[('line_Mid_North', 'line_North_Mid'),
 ('line_North_South', 'line_South_North'),
 ('line_Mid_South', 'line_South_Mid')]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...