Как написать вложенный цикл с возрастающим счетчиком, используя понимание списка? - PullRequest
1 голос
/ 27 октября 2019

Я пытаюсь оптимизировать свой код, избегая вложенных циклов и используя понимание списков в python 3. Я дам вам упрощенную версию моей проблемы с использованием вложенных циклов. Допустим, у меня есть два следующих списка:

list1 = ['a','b','c','d','e']
list2 = ['a','b','c','d','e']

Затем мне нужно получить следующий список списков:

[['aa', 'ab', 'ac', 'ad', 'ae'],
 ['bb', 'bc', 'bd', 'be'],
 ['cc', 'cd', 'ce'],
 ['dd', 'de'],
 ['ee']]

Обратите внимание, что я пытаюсь избежать выполнениядублирующие операции. То есть я не хочу получать 'ba', 'ca' и т. Д., Потому что, например, 'ab' равно 'ba' в моей задаче.

Я уже получил это, используя структуру вложенного цикла следующим образом:

outerlist = []
i = 0
for el1 in list1:
    innerlist = []
    for el2 in list2[i:]:
        innerlist.append(el1+el2)
    i += 1
    outerlist.append(innerlist)

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

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

[i+j for i in list1 for j in list2]

Какиедает мне:

['aa','ab','ac','ad','ae','ba','bb','bc','bd','be','ca','cb','cc','cd','ce','da','db','dc','dd','de','ea','eb','ec','ed','ee']

Но опять же, я не хочу "повторных" комбинаций ('ab' = 'ba', 'de' = 'ed' и т. д.), и что более важно, я не хочу вычислять b+a если у меня уже есть a+b.

Так как мне нужно делать это миллионы раз, используя очень длинные списки, я ищу наиболее эффективный способ сделать это.

1 Ответ

0 голосов
/ 27 октября 2019

С «смещением» магия ( порядковый номер позиции элемента из list1 становится смещением для нарезки list2 во избежание дублирования комбинаций):

res = [[v1 + v2 for v2 in list2[i - 1:]] for i, v1 in enumerate(list1, 1)]
print(res)

Выход:

[['aa', 'ab', 'ac', 'ad', 'ae'],
 ['bb', 'bc', 'bd', 'be'],
 ['cc', 'cd', 'ce'],
 ['dd', 'de'],
 ['ee']]
...