Идиоматическая Python-версия кода Ruby с циклом while, который проверяет оператор?

1

Следующий код 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"]
  • 0
    Да, насколько я знаю, Python не допускает заданий в условиях if ... которые иногда могут быть такими полезными.
Теги:

5 ответов

2
Лучший ответ

Идиома Python выглядит примерно так:

while True:
    i = temp.rindex('.')
    if not i:
        break
    ...
  • 2
    rindex вызывает rindex ValueError, поэтому она не будет работать так, как написано.
  • 0
    Кроме того, в if not i был бы неправ в любом случае, потому что 0 является допустимой позицией в строке. rfind() вернет -1 если не сможет найти строку.
Показать ещё 1 комментарий
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

  • 0
    Большое спасибо, особенно за эту отличную ссылку pyfaq.
  • 0
    @ Алекс: «Большое спасибо» обычно выражается в голосовании :)
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, вы увидите повсеместное понимание списков и итераторов/генераторов!

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"]

но, скорее всего, есть больше идиоматических решений...

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) если вы хотите, чтобы порядок был отменен).

Более или менее буквальный перевод вашего кода на 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)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню