如何将字典和单个项目的列表展平为应复制单个项目的列表
How to flatten a list of dicts and single items into a list where single items should be duplicated
我有这个数组:
import numpy as np
array_start = [{'Very Ripe': 5}, {'Ripe': 2}, np.nan]
我想生成一个包含各个项目的数组并复制 np.nan
值,以便我最终得到这个数组:
>>> array_end
['Very Ripe', 5, 'Ripe', 2, nan, nan]
到目前为止我已经尝试了以下方法:
>>> array_end = [item.items() if isinstance(item,dict) else np.repeat(np.nan,2) for item in array_start]
>>> array_end
[dict_items([('Very Ripe', 5)]), dict_items([('Ripe', 2)]), array([nan, nan])]
这让我有所收获,但似乎更难解压缩 dict_items
和 array_end
中的后一个数组(np.nan
s)以生成目标 array_end
:
['Very Ripe', 5, 'Ripe', 2, nan, nan]
是否必须在单列表理解中?不要让简洁成为功能代码的敌人。
这是一种使用两个列表理解的方法:
array_end = [list(*item.items()) if isinstance(item,dict) else np.repeat(np.nan,2) for item in array_start]
print(array_end)
# Output: [['Very Ripe', 5], ['Ripe', 2], array([nan, nan])]
我们在第一个列表理解中将 dict_items()
对象解包到列表中。然后,我们有一个列表列表(或 numpy 数组),我们可以 运行 另一个理解来展平它。
array_final = [y for x in array_end for y in x]
print(array_final)
# Output: ['Very Ripe', 5, 'Ripe', 2, nan, nan]
您可以遍历 array_list
中的每个项目,检查它是否是字典,如果不是,则复制该项目,如果是,则提取所有字典项目。您有多种选择可以使用
一个简单的循环 list.extend
:
import numpy as np
array_start = [{'Very Ripe': 5}, {'Ripe': 2}, np.nan]
result = []
for element in array_start:
if isinstance(element, dict):
for item in element.items():
result.extend(item)
else:
result.extend((element, element))
print(result)
# ['Very Ripe', 5, 'Ripe', 2, nan, nan]
生成器函数:
def to_flat_list(array):
for element in array:
if isinstance(element, dict):
for item in element.items():
yield from item
else:
yield element
yield element
result = list(to_flat_list(array_start))
print(result)
# ['Very Ripe', 5, 'Ripe', 2, nan, nan]
列表理解中的嵌套循环:
result = [item
for element in array_start
for pair in (element.items() if isinstance(element, dict)
else [(element, element)])
for item in pair]
print(result)
# ['Very Ripe', 5, 'Ripe', 2, nan, nan]
itertools.chain.from_iterable
:
from itertools import chain
flatten = chain.from_iterable
result = list(flatten((flatten(item.items())
if isinstance(item, dict)
else (item, item)
for item in array_start)))
print(result)
# ['Very Ripe', 5, 'Ripe', 2, nan, nan]
可能还有其他一些方法。但这些应该足够了。
我有这个数组:
import numpy as np
array_start = [{'Very Ripe': 5}, {'Ripe': 2}, np.nan]
我想生成一个包含各个项目的数组并复制 np.nan
值,以便我最终得到这个数组:
>>> array_end
['Very Ripe', 5, 'Ripe', 2, nan, nan]
到目前为止我已经尝试了以下方法:
>>> array_end = [item.items() if isinstance(item,dict) else np.repeat(np.nan,2) for item in array_start]
>>> array_end
[dict_items([('Very Ripe', 5)]), dict_items([('Ripe', 2)]), array([nan, nan])]
这让我有所收获,但似乎更难解压缩 dict_items
和 array_end
中的后一个数组(np.nan
s)以生成目标 array_end
:
['Very Ripe', 5, 'Ripe', 2, nan, nan]
是否必须在单列表理解中?不要让简洁成为功能代码的敌人。
这是一种使用两个列表理解的方法:
array_end = [list(*item.items()) if isinstance(item,dict) else np.repeat(np.nan,2) for item in array_start]
print(array_end)
# Output: [['Very Ripe', 5], ['Ripe', 2], array([nan, nan])]
我们在第一个列表理解中将 dict_items()
对象解包到列表中。然后,我们有一个列表列表(或 numpy 数组),我们可以 运行 另一个理解来展平它。
array_final = [y for x in array_end for y in x]
print(array_final)
# Output: ['Very Ripe', 5, 'Ripe', 2, nan, nan]
您可以遍历 array_list
中的每个项目,检查它是否是字典,如果不是,则复制该项目,如果是,则提取所有字典项目。您有多种选择可以使用
一个简单的循环 list.extend
:
import numpy as np
array_start = [{'Very Ripe': 5}, {'Ripe': 2}, np.nan]
result = []
for element in array_start:
if isinstance(element, dict):
for item in element.items():
result.extend(item)
else:
result.extend((element, element))
print(result)
# ['Very Ripe', 5, 'Ripe', 2, nan, nan]
生成器函数:
def to_flat_list(array):
for element in array:
if isinstance(element, dict):
for item in element.items():
yield from item
else:
yield element
yield element
result = list(to_flat_list(array_start))
print(result)
# ['Very Ripe', 5, 'Ripe', 2, nan, nan]
列表理解中的嵌套循环:
result = [item
for element in array_start
for pair in (element.items() if isinstance(element, dict)
else [(element, element)])
for item in pair]
print(result)
# ['Very Ripe', 5, 'Ripe', 2, nan, nan]
itertools.chain.from_iterable
:
from itertools import chain
flatten = chain.from_iterable
result = list(flatten((flatten(item.items())
if isinstance(item, dict)
else (item, item)
for item in array_start)))
print(result)
# ['Very Ripe', 5, 'Ripe', 2, nan, nan]
可能还有其他一些方法。但这些应该足够了。