从两个不同长度的列表([2 * n]和[2 * m])到[3 * len(unique(n [0],m [0]))的单个列表的列表理解

时间:2019-02-05 20:35:27

标签: python python-3.x list-comprehension

给出列表:

a = [
 [2, 10  ],
 [3, 120],
 [4, 30 ]
]

b = [
 [1, 10 ],
 [2, 40]
]

我如何使用列表理解,压缩,最小/最大,连接,枚举,izip_longest,地图和/或lambda返回由左变量排序的第三个列表,并将左变量的重复项加入到单行,将原始列表的位置保持在中间位置和最后位置。假设a始终位于中间位置,b始终位于最后位置,因为ab的长度可能会有所不同。

c = [
 [1, None, 10   ],
 [2, 10  , 40   ],
 [3, 120 , None ],
 [4, 30  , None ]
]

用于一行复制/粘贴

a = [[2, 0],[3, 120],[4, 30]]
b = [[1, 0],[2, 40]]
c = [[1, None, 0],[2, 0, 40],[3, 120 , None],[4, 30, None]]

感谢您的帮助。我迷上了梦co以求的单线尝试,以帮助我了解python专家的思维方式!

5 个答案:

答案 0 :(得分:7)

使用链图+列表理解:

>>> from collections import ChainMap
>>> c = ChainMap(dict(a), dict(b))
>>> [[k] + [d.get(k) for d in c.maps] for k in c]
[[1, None, 0], [2, 0, 40], [3, 120, None], [4, 30, None]]

通过这种方式,可以很容易地概括为使用两个以上的输入列表。

答案 1 :(得分:4)

如果您不介意创建一次性字典,则类似:

da = dict(a)
db = dict(b)

cc = [[k, da.get(k), db.get(k)] for k in sorted(set(da) | set(db))]

似乎可以正常工作(至少在您的示例中如此)。

  • 字典允许您通过第一个元素“查找”行
  • sorted(set(da) | set(db))接受两个字典dadb的键的排序交集。
  • 通过使用dict.get,我们可以处理行不存在的情况。 (dict.get的默认默认值为{{11}},所以我们不需要提供它,但是您可以根据需要提供。)

答案 2 :(得分:2)

您可以为此使用熊猫:

import pandas as pd
A = pd.DataFrame(dict(a),index=[0]).T
B = pd.DataFrame(dict(b),index=[0]).T
C = A.join(B,how='outer',lsuffix='l').reset_index().values
C
array([[  1.,  nan,  10.],
       [  2.,  10.,  40.],
       [  3., 120.,  nan],
       [  4.,  30.,  nan]])

如果这还不够,并且您希望使用None而不是nan,则可以执行以下操作:

pd.np.where(pd.np.isnan(C),None,C).tolist()
[[1.0, None, 10.0], [2.0, 10.0, 40.0], [3.0, 120.0, None], [4.0, 30.0, None]]

答案 3 :(得分:0)

方法1-转换为字典并执行字典合并

a = [[2, 0],[3, 120],[4, 30]]
b = [[1, 0],[2, 40]]

a_dict = dict(a)
b_dict = dict(b)
merged = [
    (key, a_dict.get(key), b_dict.get(key))
    for key in sorted(a_dict.keys() | b_dict.keys())]

方法2-合并排序列表

该算法应该更快,但仅在两个列表均按键值排序时才有效。

a = [[2, 0],[3, 120],[4, 30]]
b = [[1, 0],[2, 40]]

merged = []
a_pos, b_pos = 0, 0
while a_pos < len(a) and b_pos < len(b):
    assert a_pos == 0 or a[a_pos][0] >= a[a_pos-1][0]
    assert b_pos == 0 or b[b_pos][0] >= b[b_pos-1][0]
    if a[a_pos][0] == b[b_pos][0]:
        merged.append((a[a_pos][0], a[a_pos][1], b[b_pos][1]))
        a_pos += 1
        b_pos += 1
    elif a[a_pos][0] < b[b_pos][0]:
        merged.append((a[a_pos][0], a[a_pos][1], None))
        a_pos += 1
    else:
        merged.append((b[b_pos][0], None, b[b_pos][1]))
        b_pos += 1

while a_pos < len(a):
    merged.append((a[a_pos][0], a[a_pos][1], None))
    a_pos += 1

while b_pos < len(b):
    merged.append((b[b_pos][0], None, b[b_pos][1]))
    b_pos += 1

print(merged)

答案 4 :(得分:0)

a = np.array([
[2, 10  ],
[3, 120],
[4, 30 ]
])

b = np.array([
[1, 10 ],
[2, 40]
])

index_a=a[:,0]
value_a=a[:,1]
index_b=b[:,0]
value_b=b[:,1]
df=pd.DataFrame({"index":index_a,"a":value_a})
df2=pd.DataFrame({"index":index_b,"b":value_b})
result=pd.merge(df,df2,on="index",how="outer")
result.set_index('index',inplace=True)
result.sort_index(inplace=True)

print(result)

输出:

         a     b
index             
1        NaN  10.0
2       10.0  40.0
3      120.0   NaN
4       30.0   NaN

print(result.to_numpy())

[[ nan  10.]
[ 10.  40.]
[120.  nan]
[ 30.  nan]]