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.

Asked By: JK2018

||

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}]
Answered By: mozway

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}]
Answered By: B Remmelzwaal

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}]
Answered By: Sreyas

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}]
Answered By: RomanPerekhrest
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.