简体   繁体   中英

How can I make this looping Python code more efficient using list comprehension?

I am having trouble converting the logic of the code shown below to use Python comprehension. Can anyone help me out?

Premise

lst1 is a list of matching word pairs, lst2 is a list of matching word sextets. I am trying to "stitch" together any two of the entries in lst2 to form a loop of twelve words using the word pairs from lst1 by matching the beginning and ending words in lst2 entries with entries lst1 .

Inputs

lst1 and lst2 are 2D lists formatted as follows (with some sample data):

lst1 = [['RUNS', 'SHORT'],
        ['HIGH', 'HORSE'],
        ['TRUE', 'FALSE'],
        ['KEEP', 'HOUSE']
       ]

lst2 = [['SHORT', 'FILM', 'PROP', 'PLANE', 'RIDE', 'HIGH'],
        ['FRONT', 'DOOR', 'NAIL', 'SALON', 'DECK', 'HAND'],
        ['HORSE', 'BACK', 'FLIP', 'PHONE', 'HOME', 'RUNS']
       ]

My Code

The decidedly un-Pythonic code I have come up with is:

ans = []

for i in lst1:
    for j in lst2:
        for k in lst2:
            if j[-1] == i[0] and k[0] == i[1]:
                item = j + k
                for m in lst1:
                    if m[1] == j[0] and m[0] == k[-1]:
                        ans.append(item)
print(ans)

# becasue by definition j[0] = item[0] and k[-1] = item[-1],
# the last if statement can also be written as:

#   if m[1] == item[0] and m[0] == item[-1]:

Output

This code run on the above data produces the following output:

[['HORSE', 'BACK', 'FLIP', 'PHONE', 'HOME', 'RUNS',
  'SHORT', 'FILM', 'PROP', 'PLANE', 'RIDE', 'HIGH'],
 ['SHORT', 'FILM', 'PROP', 'PLANE', 'RIDE', 'HIGH',
  'HORSE', 'BACK', 'FLIP', 'PHONE', 'HOME', 'RUNS']
]

Note that [ans[i][-1], ans[i][0]] is in lst2 for each of the entries in ans , as required to "loop" around to the beginning again to form a circle of words. Because of the circular nature of the word loop, the two entries in ans are the same word loop and are, essentially, duplicate entries. I would need to go back and clean up this duplication with additional code that I haven't figured out yet.

(Side note: These nested for loops runs extremely slow on lists with tens of thousands of entries. Any ideas on how I can speed things up with different logic? The word lists may have duplicate entries that need to be preserved so dict() or set() won't work.)

Thank you in advance. I and a bit of a noob to Python and can use all the help I can get.

alkemyst

This is what I was looking for:

ans = [ j + k  for i in corner
               for w in corner
               for j in chain
               for k in chain
               if j[-1] == i[0] and k[0] == i[1]
               if w[1] == j[0] and w[0] == k[-1]
               ]
print(ans)

It is marginally faster. Thank you for all your comments.

alkemyst

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM