Lists manipulation with indexs
Question:
I have two lists.
List A :
A = ["apple","cherry","pear","mango","banana","grape","kiwi","orange","pineapple"]
List B :
B = [{"offset":0, "xx":789},{"offset":3, "xx":921},{"offset":6, "xx":89}]
The idea is to use the offset from each item in B as an index offset for setting the xx values in our results array.
For instance, this would be the expected result:
C=[
{"fruit":"apple","xx":789},
{"fruit":"cherry","xx":789},
{"fruit":"pear","xx":789},
{"fruit":"mango","xx":921},
{"fruit":"banana","xx":921},
{"fruit":"grape","xx":921},
{"fruit":"kiwi","xx":89},
{"fruit":"orange","xx":89},
{"fruit":"pineapple","xx":89},
]
For example, B[0] has "offset" of 0. this means that C of index >= 0 will have an "xx" value of B[0][‘xx’]. Then we have B[0][‘offset’] of 3 that will set new "xx" values to the C items with index >= 3 and so on.
I am able to acheive a similar result using a dataframes and pandas. But since pandas library is quite heavy, I am requested to do it without using pandas.
Answers:
What about using a simple loop?
# rework B in a better format
dic = {d['offset']:d['xx'] for d in B}
# {0: 789, 3: 921, 6: 89}
C = []
v = None
for i, a in enumerate(A):
v = dic.get(i, v) # if we reached a threshold, update the value
C.append({'fruit':a, 'xx': v})
print(C)
Output:
[{'fruit': 'apple', 'xx': 789},
{'fruit': 'cherry', 'xx': 789},
{'fruit': 'pear', 'xx': 789},
{'fruit': 'mango', 'xx': 921},
{'fruit': 'banana', 'xx': 921},
{'fruit': 'grape', 'xx': 921},
{'fruit': 'kiwi', 'xx': 89},
{'fruit': 'orange', 'xx': 89},
{'fruit': 'pineapple', 'xx': 89}]
If the structure of B is required to be this way, you can do this:
A = ["apple","cherry","pear","mango","banana","grape","kiwi","orange","pineapple"]
B = [{"offset":0, "xx":789},{"offset":3, "xx":921},{"offset":6, "xx":89}]
C = []
B_iter = 0
for i, fruit in enumerate(A):
# check if not the last element and next element is start of new range
if B[B_iter] != B[-1] and B[B_iter+1]["offset"] == i:
B_iter += 1
C.append({"fruit": fruit, "xx": B[B_iter]["xx"]})
print(C)
Output:
[{'fruit': 'apple', 'xx': 789},
{'fruit': 'cherry', 'xx': 789},
{'fruit': 'pear', 'xx': 789},
{'fruit': 'mango', 'xx': 921},
{'fruit': 'banana', 'xx': 921},
{'fruit': 'grape', 'xx': 921},
{'fruit': 'kiwi', 'xx': 89},
{'fruit': 'orange', 'xx': 89},
{'fruit': 'pineapple', 'xx': 89}]
If the offset is always multiple of 3 you can simply do integer division to map the actual index to offset.
A = ["apple","cherry","pear","mango","banana","grape","kiwi","orange","pineapple"]
B = [{"offset": 0, "xx": 789}, {"offset": 3, "xx": 921}, {"offset": 6, "xx": 89}]
C = [{"fruit": fruit,"xx": B[int(idx/3)]["xx"]} for idx, fruit in enumerate(A)]
Output:
[{'fruit': 'apple', 'xx': 789},
{'fruit': 'cherry', 'xx': 789},
{'fruit': 'pear', 'xx': 789},
{'fruit': 'mango', 'xx': 921},
{'fruit': 'banana', 'xx': 921},
{'fruit': 'grape', 'xx': 921},
{'fruit': 'kiwi', 'xx': 89},
{'fruit': 'orange', 'xx': 89},
{'fruit': 'pineapple', 'xx': 89}]
If arranging offsets you can obtain the needed result with a single list comprehension:
offsets = [d['offset'] for d in B] + [None]
C = [{'fruit': f, 'xx': B[i]['xx']} for i in range(len(offsets) - 1)
for f in A[offsets[i]: offsets[i + 1]]]
[{'fruit': 'apple', 'xx': 789},
{'fruit': 'cherry', 'xx': 789},
{'fruit': 'pear', 'xx': 789},
{'fruit': 'mango', 'xx': 921},
{'fruit': 'banana', 'xx': 921},
{'fruit': 'grape', 'xx': 921},
{'fruit': 'kiwi', 'xx': 89},
{'fruit': 'orange', 'xx': 89},
{'fruit': 'pineapple', 'xx': 89}]
I have two lists.
List A :
A = ["apple","cherry","pear","mango","banana","grape","kiwi","orange","pineapple"]
List B :
B = [{"offset":0, "xx":789},{"offset":3, "xx":921},{"offset":6, "xx":89}]
The idea is to use the offset from each item in B as an index offset for setting the xx values in our results array.
For instance, this would be the expected result:
C=[
{"fruit":"apple","xx":789},
{"fruit":"cherry","xx":789},
{"fruit":"pear","xx":789},
{"fruit":"mango","xx":921},
{"fruit":"banana","xx":921},
{"fruit":"grape","xx":921},
{"fruit":"kiwi","xx":89},
{"fruit":"orange","xx":89},
{"fruit":"pineapple","xx":89},
]
For example, B[0] has "offset" of 0. this means that C of index >= 0 will have an "xx" value of B[0][‘xx’]. Then we have B[0][‘offset’] of 3 that will set new "xx" values to the C items with index >= 3 and so on.
I am able to acheive a similar result using a dataframes and pandas. But since pandas library is quite heavy, I am requested to do it without using pandas.
What about using a simple loop?
# rework B in a better format
dic = {d['offset']:d['xx'] for d in B}
# {0: 789, 3: 921, 6: 89}
C = []
v = None
for i, a in enumerate(A):
v = dic.get(i, v) # if we reached a threshold, update the value
C.append({'fruit':a, 'xx': v})
print(C)
Output:
[{'fruit': 'apple', 'xx': 789},
{'fruit': 'cherry', 'xx': 789},
{'fruit': 'pear', 'xx': 789},
{'fruit': 'mango', 'xx': 921},
{'fruit': 'banana', 'xx': 921},
{'fruit': 'grape', 'xx': 921},
{'fruit': 'kiwi', 'xx': 89},
{'fruit': 'orange', 'xx': 89},
{'fruit': 'pineapple', 'xx': 89}]
If the structure of B is required to be this way, you can do this:
A = ["apple","cherry","pear","mango","banana","grape","kiwi","orange","pineapple"]
B = [{"offset":0, "xx":789},{"offset":3, "xx":921},{"offset":6, "xx":89}]
C = []
B_iter = 0
for i, fruit in enumerate(A):
# check if not the last element and next element is start of new range
if B[B_iter] != B[-1] and B[B_iter+1]["offset"] == i:
B_iter += 1
C.append({"fruit": fruit, "xx": B[B_iter]["xx"]})
print(C)
Output:
[{'fruit': 'apple', 'xx': 789},
{'fruit': 'cherry', 'xx': 789},
{'fruit': 'pear', 'xx': 789},
{'fruit': 'mango', 'xx': 921},
{'fruit': 'banana', 'xx': 921},
{'fruit': 'grape', 'xx': 921},
{'fruit': 'kiwi', 'xx': 89},
{'fruit': 'orange', 'xx': 89},
{'fruit': 'pineapple', 'xx': 89}]
If the offset is always multiple of 3 you can simply do integer division to map the actual index to offset.
A = ["apple","cherry","pear","mango","banana","grape","kiwi","orange","pineapple"]
B = [{"offset": 0, "xx": 789}, {"offset": 3, "xx": 921}, {"offset": 6, "xx": 89}]
C = [{"fruit": fruit,"xx": B[int(idx/3)]["xx"]} for idx, fruit in enumerate(A)]
Output:
[{'fruit': 'apple', 'xx': 789},
{'fruit': 'cherry', 'xx': 789},
{'fruit': 'pear', 'xx': 789},
{'fruit': 'mango', 'xx': 921},
{'fruit': 'banana', 'xx': 921},
{'fruit': 'grape', 'xx': 921},
{'fruit': 'kiwi', 'xx': 89},
{'fruit': 'orange', 'xx': 89},
{'fruit': 'pineapple', 'xx': 89}]
If arranging offsets you can obtain the needed result with a single list comprehension:
offsets = [d['offset'] for d in B] + [None]
C = [{'fruit': f, 'xx': B[i]['xx']} for i in range(len(offsets) - 1)
for f in A[offsets[i]: offsets[i + 1]]]
[{'fruit': 'apple', 'xx': 789},
{'fruit': 'cherry', 'xx': 789},
{'fruit': 'pear', 'xx': 789},
{'fruit': 'mango', 'xx': 921},
{'fruit': 'banana', 'xx': 921},
{'fruit': 'grape', 'xx': 921},
{'fruit': 'kiwi', 'xx': 89},
{'fruit': 'orange', 'xx': 89},
{'fruit': 'pineapple', 'xx': 89}]