I have a list of dicts and I wants to get the elements at index `0,1,list/2,(list/2 1),2,3,....
As an example i have following list of dicts.
test = [{'aa':0},{'ab':0},{'ba':0},{'bb':0},{'ca':0},{'cb':0},{'da':0},{'db':0},{'ea':0},{'eb':0},{'fa':0},{'fb':0}]
output: [{'aa':0},{'ab':0},{'da':0},{'db':0},{'ba':0},{'bb':0},{'ea':0},{'eb':0},{'ca':0},{'cb':0},{'fa':0},{'fb':0}]
Is there an easy way to do this? If is do sommeting like this.
[item for sublist in zip(test[:middel], test[middel:]) for item in sublist]
I get following output.
[{'aa':0},
{'da':0},
{'ab':0},
{'db':0},
{'ba':0},
{'ea':0},
{'bb':0},
{'eb':0},
{'ca':0},
{'fa':0},
{'cb':0},
{'fb':0}]
if I split test in 2 (in the middle)
list1 = [{'aa': 0}, {'ab': 0}, {'ba': 0}, {'bb': 0}, {'ca': 0}, {'cb': 0}]
list2 = [{'da': 0}, {'db': 0}, {'ea': 0}, {'eb': 0}, {'fa': 0}, {'fb': 0}]
I wants a new list with the first 2 dicts of list1, then the 2 first of list2, then the middle 2 of list1, then the middle 2 of list2 then the last 2 of list1, then the last 2 of list2
The real dicts does look like this
{'datasource': 'InfluxDB', 'fieldConfig': {'defaults': {'mappings': [], 'thresholds': {'mode': 'absolute', 'steps': [{'color': 'yellow', 'value': None}, {'color': 'green', 'value': 50}, {'color': 'red', 'value': 400}]}, 'unit': 'kwatt'}, 'overrides': []}, 'gridPos': {'h': 5, 'w': 4, 'x': 14, 'y': 14}, 'id': 104, 'options': {'colorMode': 'background', 'graphMode': 'none', 'justifyMode': 'auto', 'orientation': 'horizontal', 'reduceOptions': {'calcs': ['lastNotNull'], 'fields': '', 'values': False}, 'text': {'titleSize': 16, 'valueSize': 16}, 'textMode': 'auto'}, 'pluginVersion': '8.1.1', 'targets': [{'alias': 'Gevraagd vermogen', 'groupBy': [{'params': ['$__interval'], 'type': 'time'}, {'params': ['null'], 'type': 'fill'}], 'orderByTime': 'ASC', 'policy': 'default', 'refId': 'B', 'resultFormat': 'time_series', 'select': [[{'params': ['GV'], 'type': 'field'}, {'params': [], 'type': 'last'}, {'params': [' / 10'], 'type': 'math'}]], 'tags': []}, {'alias': 'Geleverd vermogen', 'groupBy': [{'params': ['$__interval'], 'type': 'time'}, {'params': ['null'], 'type': 'fill'}], 'orderByTime': 'ASC', 'policy': 'default', 'refId': 'A', 'resultFormat': 'time_series', 'select': [[{'params': ['Actief vermogen'], 'type': 'field'}, {'params': [], 'type': 'last'}]], 'tags': []}], 'timeFrom': None, 'timeShift': None, 'type': 'stat'}
CodePudding user response:
You example is a bit complex and can be simplified to:
Change this input:
i = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
into this output:
o = [0, 1, 6, 7, 2, 3, 8, 9, 4, 5, 10, 11]
using the algorithm you describe.
This can be achieved easily using iterators:
def reorder(l, by=2):
half = len(l)//2
a, b = iter(l[:half]), iter(l[half:])
out = []
for i in range(len(l)//(2*by)):
for i in range(by):
out.append(next(a))
for i in range(by):
out.append(next(b))
return out
o = reorder(i)
on the provided data:
>>> reorder(test)
[{'aa': 0},
{'ab': 0},
{'da': 0},
{'db': 0},
{'ba': 0},
{'bb': 0},
{'ea': 0},
{'eb': 0},
{'ca': 0},
{'cb': 0},
{'fa': 0},
{'fb': 0}]
CodePudding user response:
new_list = []
l_2 = int(len(test) / 2)
for one, two, mid_one, mid_two in zip(test[:l_2:2], test[1:l_2:2], test[l_2::2], test[1 l_2 :: 2]):
new_list.append(one)
new_list.append(two)
new_list.append(mid_one)
new_list.append(mid_two)
print(new_list)
CodePudding user response:
I see a brute force solution...
output = []
for c1 in 'aedbcf':
for c2 in 'ab':
output.append({c1 c2 : 0})
print(output)
Otherwise, the trick you need is to pair up your elements on the first letters before you try to rearrange them, not directly slice your initial list
CodePudding user response:
I think this can be a solution that avoids a for loop:
from itertools import pairwise
inputs = [1, 2, 3, 4, 5, 6, 7, 8]
pair = list(pairwise(inputs)) # -> [(1, 2), (2, 3), (3, 4), ...]
del pair[1::2] # remove [(2, 3), (4, 5), ...]
first, second = pair[:len(pair)//2], pair[len(pair)//2:] # first = [(1, 2), (3, 4)], second = [(5, 6), (7, 8)]
def merge_tuple(x):
return x[0] x[1]
output = list(map(merge_tuple, zip(first, second))) # -> [(1, 2, 5, 6), (3, 4, 7, 8)]
output = output[0] output[1]
If your python version is too old to have pairwise you can use this
