2012-03-13 2 views
1

次のコードのRubyコードは、ソース文字列を繰り返し、 '。'で区切られた累積単語のリストを生成します。最後の '。'の後の文字以外の文字。例えば文をテストするwhileループを持つRubyコードの慣用的なPython版ですか?

、結果は

[ "会社"、 "Company.Dept.Group"、 "Company.Dept"] ... なり 'Company.Dept.Group.Team' のソース文字列を与えます

Pythonのwhileループ(私が信じる)は、下記のような式だけではなく、式だけをテストすることを考えれば、これを慣用句のPythonでどのように書くのが最適でしょうか?

while True: 
    i = temp.rindex('.') 
    if not i: 
     break 
    ... 
+0

はい、私の知る限り、Pythonは許可していませんassigments場合では時々、このような便利なものと考えられる条件...。 – moooeeeep

答えて

2

ザ・Pythonのイディオムは次のようなものです。あなたはPythonに慣れている場合はPythonにあなたのコードの

多かれ少なかれ、直訳では、どこでも、リストの内包表記とイテレータ/発電機を参照してください

source = 'Company.Dept.Group.Team' 
results = [] 
temp = source 

while True: 
    try: 
     i = temp.rindex('.') 
     temp = temp[:i]  
     results.append(temp) 
    except ValueError: 
     break 
print(results) 
+2

'rindex'はValueErrorを発生させます。したがって、これは書き込まれたようには動作しません。 – DSM

+0

また、もし '0 'が文字列中の有効な位置であるため、' if not i'は間違っています。 'rfind()'は文字列が見つからなかった場合に '-1'を返します。 –

+0

私はこれを答えとしてマークしました。なぜなら、文をテストするRuby whileループと同じPythonの慣用句として 'while True:'を使用したからです。私が使用するかもしれない正確なコードは、rindex()の代わりにrfind()であり、次に-1をテストして中断すると思います。どうもありがとう! – Aryeh

0

私は

>>> import re 
>>> source = 'Company.Dept.Group.Team' 
>>> results = [source[:m.start()] for m in re.finditer(r"\.", source)] 
>>> results 
['Company', 'Company.Dept', 'Company.Dept.Group'] 

(あなたが順序を逆にしたい場合はreversed(results)を使用する)だろう:

#ruby 
source = 'Company.Dept.Group.Team' 
results = [] 

temp = source.clone 
while (i = temp.rindex('.')) # test statement not supported in Python? 
    temp = temp[0...i] 
    results << temp 
end 

p results # >> ["Company.Dept.Group", "Company.Dept", "Company"] 
1
>>> source = 'Company.Dept.Group.Team' 
>>> last = [] 
>>> [last.append(s) or '.'.join(last) for s in source.split('.')[:-1]] 
['Company', 'Company.Dept', 'Company.Dept.Group'] 
+1

副作用を伴うリストの理解?通常、これは "慣用的なPython"とは酷評されていません。 –

1

だろう!一般的にこれを達成するためにはPythonが

source = 'Company.Dept.Group.Team' 

# generate substrings 
temp = source.split(".") 
results = [".".join(temp[:i+1]) for i,s in enumerate(temp)] 

# pop the team (alternatively slice the team out above) 
results.pop() 

# reverse results 
result.reverse() 

print result # should yield ["Company.Dept.Group", "Company.Dept", "Company"] 

可能性がありますが、おそらくより多くの慣用的な解決策がある...

1

、私はおそらく行いたい:

source = 'Company.Dept.Group.Team' 
split_source = source.split('.') 
results = ['.'.join(split_source[0:x]) for x in xrange(len(split_source) - 1, 0, -1)] 
print results 

リテラル翻訳はもっと似ています:

source = 'Company.Dept.Group.Team' 

temp = source 
results = [] 
while True: 
    i = temp.rfind('.') 
    if i < 0: 
     break 
    temp = temp[0:i] 
    results.append(temp) 

print results 

それとも、あなたが好む場合:

source = 'Company.Dept.Group.Team' 

temp = source 
results = [] 
try: 
    while True: 
     temp = temp[0:temp.rindex('.')] 
     results.append(temp) 
except ValueError: 
    pass 
print results 

または:

source = 'Company.Dept.Group.Team' 

temp = source 
results = [] 
i = temp.rfind('.') 
while i > 0: 
    temp = temp[0:i] 
    results.append(temp) 
    i = temp.rfind('.') 

print results 

あなたが指摘するように、表現が少し洗練これらのケースを作るよう、あなたが割り当てを扱うことができないという事実。私は前者の事例、すなわち「真実」は最後のものよりも一般的だと思います。

は、より多くの背景については、この記事ではなかなか良さそうです:http://effbot.org/pyfaq/why-can-t-i-use-an-assignment-in-an-expression.htm

+0

多くのおかげで、特にその優れたpyfaqリンクに感謝します。 – Aryeh

+0

@Alex:「多くの感謝」は通常、アップアップで表現されます:) –

関連する問題