3

私は2つの文字列を持っています:

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

存在する場合は l1 の値を使用し、存在しない場合は l2 の値を渡す Python (2.7) リストを作成したいと考えています。私は作業コードを持っていますが、リスト内包表記を使用しても、これを行うにはもっと 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']

どちらが正しい。

------- edit したがって、以下の 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))]
4

2 に答える 2

6

あなたの例で動作します

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='')]
于 2013-05-26T12:09:54.753 に答える
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']
于 2013-05-26T12:09:04.597 に答える