我有两个字符串:
s1 = "Brendon, Melissa, Jason, , McGuirk" #the gauranteed string in format "x, y, z"
s2 = "brandon,melissa,jxz ,paula,coach" #the messy string
Run Code Online (Sandbox Code Playgroud)
并且想创建一个Python(2.7)列表,如果它存在则使用l1中的值,否则传递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)]
Run Code Online (Sandbox Code Playgroud)
列表"final"现在包含:
['Brendon', 'Melissa', 'Jason', 'paula', 'McGuirk']
Run Code Online (Sandbox Code Playgroud)
哪个是对的.
-------编辑所以,看看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))]
Run Code Online (Sandbox Code Playgroud)
适用于您的示例
s1 = "Brendon, Melissa, Jason, , McGuirk"
s2 = "brandon, melissa, jxz, paula, coach"
print [a or b for a, b in zip(s1.split(', '), s2.split(', '))]
Run Code Online (Sandbox Code Playgroud)
稍微更通用的一个可以适应:
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='')]
Run Code Online (Sandbox Code Playgroud)