假设我有以下列表:
list1 = ['MI', '', 'NY', '', 'AR', '']
list2 = ['', 'MS', '', 'OH', '', '']
如果list1中存在缺失值或空字符串,我想用list2中的相应值覆盖空字符串。有没有一种有效的方法来执行此操作而无需迭代list1中的每个项目?以下是我目前的解决方案:
list1 = ['MI', '', 'NY', '', 'AR', '']
list2 = ['', 'MS', '', 'OH', '', '']
counter = 0
for each in list1:
counter = counter + 1
if len(each) == 0:
list1[counter-1] = list2[counter-1]
print(list1)
>>> ['MI', 'MS', 'NY', 'OH', 'AR', '']
我尝试将我的列表转换为pandas数据框并使用pandas.DataFrame.update()
,但没有得到我想要的结果。类似的问题在here解决,但在R.
答案 0 :(得分:2)
有一种更'Pythonic'的方法(使用列表推导),但最后仍然会得到一个迭代:
[x or y for x, y in zip(list1, list2)]
答案 1 :(得分:1)
你可以使用pandas pandas.Series.where()
方法,但我想还有一个迭代:
>>> s1 = pd.Series(list1)
>>> s2 = pd.Series(list2)
>>> s1.where(s1 != '', s2)
0 MI
1 MS
2 NY
3 OH
4 AR
5
关于您的原始方法,您不必拥有自己的计数器,顺便说一句,您可以使用enumerate()
方法:
>>> def isnull1(list1, list2):
... res = []
... for i, x in enumerate(list1):
... if not x:
... res.append(list2[i])
... else:
... res.append(x)
... return res
...
>>> isnull1(list1, list2)
['MI', 'MS', 'NY', 'OH', 'AR', '']
>>> map(lambda x: x[1] if not x[0] else x[0], zip(list1, list2))
['MI', 'MS', 'NY', 'OH', 'AR', '']
如果您不需要立即列出,最好使用generators
:
>>> def isnull2(list1, list2):
... for i, x in enumerate(list1):
... if not x:
... yield list2[i]
... else:
... yield x
...
>>> list(isnull2(list1, list2))
['MI', 'MS', 'NY', 'OH', 'AR', '']
>>> from itertools import izip, imap
>>> list(imap(lambda x: x[1] if not x[0] else x[0], izip(list1, list2)))
['MI', 'MS', 'NY', 'OH', 'AR', '']
答案 2 :(得分:0)
也许这会有所帮助:
def list_default(l1, l2):
i1 = iter(l1)
i2 = iter(l2)
for i in i1:
next_default = i2.next()
if not i:
yield next_default
else:
yield i
list1 = ['MI', '', 'NY', '', 'AR', '']
list2 = ['', 'MS', '', 'OH', '', '']
print(list(list_default(list1, list2)))
>>> ['MI', 'MS', 'NY', 'OH', 'AR', '']
您必须迭代序列以查找缺失值,使用前一个功能可以避免跟踪列表索引。
抱歉我的英文