2013-05-26 66 views
3

我有两个字符串:Python来筛选另一个CSV列表中的逗号分隔的列表

s1 = "Brendon, Melissa, Jason, , McGuirk" #the gauranteed string in format "x, y, z" 
s2 = "brandon,melissa,jxz ,paula,coach" #the messy string 

,并希望创建一个使用值L1如果存在一个Python(2.7)名单,否则通通过l2中的值。我有工作代码,但即使列表理解,我觉得可能会有更多的Pythonic这样做。任何想法可能是什么?

l1 = [x.strip() for x in s1.split(',')] 
l2 = [x.strip() for x in s2.split(',')] 
f = lambda s: s[1] if s[1] else s[0] 
final = [f(x) for x in zip(l2, l1)] 

列表 “最终” 现在包含:

['Brendon', 'Melissa', 'Jason', 'paula', 'McGuirk'] 

这是正确的。

-------编辑 因此,在下面Jon的答案中,a或b看起来似乎是最简单,最可读的方法。我把字符串清理移到了一个小函数中,并且以此结束。任何进一步的改进?

trim_csv = lambda csv: [s.strip() for s in csv.split(',')] 
print [a or b for a, b in zip(trim_csv(s1), trim_csv(s2))] 
+0

什么,如果有遗漏的S1和S2值?我在这篇文章中看到的两个答案返回一个长度为4的列表(即他们放弃它)。 – Spacedman

+1

@Spacedman他们不放弃它 - 他们保留元素作为'''' –

+0

如果逗号之间没有空格 - 可能是因为你分割了“逗号空间” – Spacedman

回答

6

Works为你的榜样

s1 = "Brendon, Melissa, Jason, , McGuirk" 
s2 = "brandon, melissa, jxz, paula, coach" 

print [a or b for a, b in zip(s1.split(', '), s2.split(', '))] 

较笼统的一个可者进行调整:

import re 
from itertools import izip_longest, ifilter, imap 

s1 = "Brendon, Melissa, Jason, , McGuirk" 
s2 = "brandon, melissa, jxz, paula, coach" 


def take_first_not_empty(*args): 
    splitter = re.compile(r'\s*?,\s*').split 
    words = imap(splitter, args) 
    return [next(ifilter(None, vals), '') for vals in izip_longest(*words, fillvalue='')] 
+1

“或”是答案。 – georg

+0

+1使用'或'。 –

+0

我不确定我了解您的通用示例的用法。我尝试过:[take_first_not_empty(a,b)for a,b in zip(s1.split(','),s2.split(','))] 然后它将项目列表作为单独列表返回。例如: [['Brendon'],['Melissa'],['Jason'],['paula'],['McGuirk']] –

2

是这样的吗?

>>> s1 = "Brendon, Melissa, Jason, , McGuirk" 
>>> s2 = "brandon, melissa, jxz, paula, coach" 
>>> [x if x else y for x,y in zip(s1.split(', '),s2.split(', '))] 
['Brendon', 'Melissa', 'Jason', 'paula', 'McGuirk'] 
+0

我不知道我可以指望总是分开逗号空间的列表。我会更新这个问题。 –