I have a list of lists as follows.
ogList = [[a], [b], [], [], [c], [d], []]
I'd like each empty list to be populated like so, based on the last list which does have a value.
outputList = [[a], [b], [b], [b], [c], [d], [d]]
So far I have assembled the following.
copy = 0
for list in ogList:
for list in list:
for number in list:
if number:
copy = number
print copy
if not number:
list.append(copy)
However append(copy) simply adds the value stored in copy to the second index of the list. Thus it occurred that I might use insert(0, copy), but this freezes up my system (infinite loop?). Here I am requesting assistance. How can I accomplish this?
I also greatly appreciate anyone willing to explain to this complete beginner what kinds of utter nonsense I might be employing here (like instantiating copy before the for loop?). Thank you everyone.
CodePudding user response:
a=1;b=2;c=3;d=4
ogList = [[a], [b], [], [], [c], [d], []]
copy = 0
for index, list in enumerate(ogList):
if list: #if list is not empty
copy = list[-1] # last element
else:
ogList[index] = [copy]
print(ogList)
In your code, you went one level too deep (used too many for loops).
Also in Python lists are mutable, so when you tried to modify a list in a for loop, then only a copy of it could be overwritten, not the original one (append()
is an exception to this). Generally, if you use indexes, you can overwrite the original values.
In my example I used the enumerate()
function, which iterates over an iterable (e.g. a list), and returns an index and the value for it in each iteration. I can use the value to read, and the index to modify it.
In the else clause I completely overwrite the sublist, so I need to put [
and ]
to indicate that copy
is in a list.
CodePudding user response:
Try this:
ogList = [["a"], ["b"], [], [], ["c"], ["d"], []]
temp = ogList[0]
for i in range(1, len(ogList)):
if ogList[i] == []:
ogList[i] = temp
else:
temp = ogList[i]
If you use variables a, b, c, d in array instead of values "a", "b", "c", "d", they must be assigned before array's assignment.
Don't use the same variable names in nested loops. That's why your program hangs.
CodePudding user response:
Not very Pythonic, but it works:
og_list = [['a'], ['b'], [], [], ['c'], ['d'], []]
prev = []
for i in range(len(og_list)):
if len(og_list[i]) == 0:
og_list[i] = prev
else:
prev = og_list[i]
print(og_list)
Result:
[['a'], ['b'], ['b'], ['b'], ['c'], ['d'], ['d']]
Now let's go over your snippet:
copy = 0
for list in ogList: # cool
for list in list: # list in list? would be better to use something like sublist in list to avoid confusion
for number in list: # number? what if the inner list stores something that is not a number?
if number: # so basically if number is not None or False - why?
copy = number
print copy # print(copy), you forgot the brackets (unless it's Python 2, in which case I have no idea about proper syntax, sorry)
if not number: # you could've used an else clause here, a number is or a number is not, these cannot be true at the same time
list.append(copy)
The problem with your code begins at the for number in list
line: this only iterates over elements of a sublist if that sublist itself is not empty - checks you tried executing inside that for loop were therefore useless (if not number
, I assume, was supposed to check if a sublist is empty, but you'd never get here with an empty sublist).
CodePudding user response:
All earlier posts are working pretty well, but it seems that there are some room for improvements.
So here just offer another simpler, maybe more Pythonic approach for your reference:
Note - this program will only work on the assumption that first item in the original list is not empty, as the sample input shown. Since the OP's requirement does not mention that situation.
ogList = [['a'], ['b'], [], [], ['c'], ['d'], []]
out = [ogList[0]] # initialize to first item
#for i, lst in enumerate(ogList[1:]): # only if you need idx, item
for lst in ogList[1:]: # directly access the item, avoid idx
if not lst: # empty list encountered
out.append(out[-1]) # add last item
else:
out.append(lst) # current lst
print(out) # to confirm the output
# OR this easy way:
expected = [['a'], ['b'], ['b'], ['b'], ['c'], ['d'], ['d']]
assert out == expected # silence, because they're same