2

I have a nest list:

listSchedule = [[list1], [list2], etc..]]

I have another list and I want to append to each nested list the element of this list if the first element of each matches a string.

I can do it but I wonder if there is a more 'pythonic' way, using list comprehension?

index = 0;
for row in listSchedule:
   if row[0] == 'Download':
      row[3] = myOtherList[index]
      index +=1
2
  • 2
    Is there a reason you're not just using a dict (or if Download might appear multiple times, a multi-dict like collections.defaultdict(list)) or something? Needing to loop over every element to find a "header" to append data to sounds an awful lot like the case where you'd want a dict. Commented Sep 20, 2018 at 13:20
  • 1
    The more I look at this, the more I suspect an XY problem. Can you provide more details about the problem so we're not just applying touch-ups to a bad design? Even a real minimal reproducible example would be helpful (as written, this code guarantees an IndexError, since it assigns to row[3], but the listSchedule you provided is a list of len 1 lists, so any index but row[0] would error out. Commented Sep 20, 2018 at 14:20

4 Answers 4

4

Your code is very readable, I would not change it.

With a list comprehension you could write something like:

for index, row in enumerate([row for row in listSchedule if row[0] == 'Download']):
    row[3] = myOtherList[index]
Sign up to request clarification or add additional context in comments.

1 Comment

Omit the brackets; no need for a temporary list here (enumerate is perfectly happy to work with generators, it doesn't need full sequences). Without the brackets, enumerate(row for row in listSchedule if row[0] == 'Download') enumerates a generator expression that produces the rows lazily, no potentially large temporary lists needed.
1

you could try that but make a copy of the otherlist to not lose the info:

[row+[myotherlist.pop(0)] if row[0]=='Download' else row for row in listScheduel]

for example:

list = [['Download',1,2,3],[0,1,2,3],['Download',1,2,3],['Download',1,2,3]]
otherlist = [0,1,2,3,4]
l = [ row+[otherlist.pop(0)] if row[0]=='Download' else row for row in list]

Output:

[['Download', 1, 2, 3, 0],
[0, 1, 2, 3],
['Download', 1, 2, 3, 1],
['Download', 1, 2, 3, 2]]

Comments

0

If you want to truly append, why not use row.append(myOtherList[index])? That way you avoid IndexErrors

i = 0

for row in listSchedule:
    if row[0]=="Download":
        row.append(myOtherList[i])
        i+=1

Comments

0

We can use a queue and pop its values one by one when we meet the condition. To avoid copying of data let's implement the queue as a view over myOtherList using an iterator (thanks to ShadowRanger).

queue = iter(myOtherList)

for row in listSchedule:
    if row[0] == "Download":
        row.append(next(iter))

1 Comment

You could save the temporary deque with just queue = iter(myOtherList), and row.append(next(queue)). Assumes myOtherList isn't being otherwise modified in the loop, but otherwise gets the same behavior, with no overhead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.