Следующий код Ruby кода будет итерировать исходную строку и составить список кумулятивных слов, разделенных символом '.' характер, за исключением тех, что были после последнего ".".
Например, укажите исходную строку "Company.Dept.Group.Team", результат будет... ["Company.Dept.Group", "Company.Dept", "Компания"]
Учитывая, что цикл while в Python (я полагаю) проверит только выражение, а не оператор, как показано ниже, как лучше всего написать это в идиоматическом Python?
#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"]
Идиома Python выглядит примерно так:
while True:
i = temp.rindex('.')
if not i:
break
...
rindex
вызывает rindex
ValueError, поэтому она не будет работать так, как написано.
if not i
был бы неправ в любом случае, потому что 0
является допустимой позицией в строке. rfind()
вернет -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-ti-use-an-assignment-in-an-expression.htm
>>> source = 'Company.Dept.Group.Team'
>>> last = []
>>> [last.append(s) or '.'.join(last) for s in source.split('.')[:-1]]
['Company', 'Company.Dept', 'Company.Dept.Group']
Если вы привыкнете к Python, вы увидите повсеместное понимание списков и итераторов/генераторов!
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"]
но, скорее всего, есть больше идиоматических решений...
я бы сделал
>>> 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)
если вы хотите, чтобы порядок был отменен).
Более или менее буквальный перевод вашего кода на 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)