Issue
I am trying to replace all None
values in all sublists within a list to incremental numbers starting from 0 but excluding the numbers from the skip list. And there is one more requirement. If first element of a sublist matches to any other sublists' first element, then they all need to have the same value that replaces None
in them if present. This is what I could try so far.
skip = [1,2]
a = [[1, None, 2], [3, 4, 5], [1, None, 7], [8, 9, 10],[11, None, 12]]
b = 0
d = {}
for i in range(len(a)):
if a[i][1]==None:
if b in skip:
print("found b in skip")
b = b + 1
if a[i][1] in d.keys():
a[i][1] = d[a[i][1]]
else:
a[i][1] = b
d[a[i][0]] = b
b = b + 1
print(d)
print(a)
Output:
found b in skip
{1: 2, 11: 3}
[[1, 0, 2], [3, 4, 5], [1, 2, 7], [8, 9, 10], [11, 3, 12]]
Expected output:
[[1, 0, 2], [3, 4, 5], [1, 0, 7], [8, 9, 10], [11, 3, 12]]
Solution
You're looking up the wrong element in the cache in a couple places, and not skipping properly when the skip
list contains consecutive elements. Here's the minimal fix with inline comments indicating changed lines:
skip = [1,2]
a = [[1, None, 2], [3, 4, 5], [1, None, 7], [8, 9, 10],[11, None, 12]]
b = 0
d = {}
for i in range(len(a)):
if a[i][1]==None:
while b in skip: # Loop until skipped all elements in skip
print("found b in skip")
b = b + 1
if a[i][0] in d.keys(): # Check for first, not second element
a[i][1] = d[a[i][0]] # Use first element, not second, for lookup
else:
a[i][1] = b
d[a[i][0]] = b # Indent so we only set cached value on cache miss
b = b + 1 # Indent so we only increment b on new first element
print(d)
print(a)
And here's a more heavily modified version that is somewhat more Pythonic, using names, not indexing (when possible):
skip = {1,2} # Use set instead of list; if skip is large, list membership check will be expensive, set will stay cheap
a = [[1, None, 2], [3, 4, 5], [1, None, 7], [8, 9, 10],[11, None, 12]]
b = 0
d = {}
for sublist in a: # Loop over values instead of indexing a over and over, C-style (slow and less readable)
first, middle, _ = sublist # Unpack to useful names (reducing risk of misindexing, and making more readable code)
# Not unpacking in for loop itself because we need to reassign elements of sublist
if middle is None: # Always use is/is not to compare to None
while b in skip:
b += 1 # Use += to avoid repeating variable name
if first in d: # No need for .keys(); "in d" has same effect as "in d.keys()" and avoids creating unnecessary keys view
sublist[1] = d[first] # Indexing needed for assignment to modify original list
else:
sublist[1] = d[first] = b # Can populate cache and reassign middle value all at once
b += 1
print(d)
print(a)
Either version gets the expected output from the question.
Answered By - ShadowRanger
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.