2010-07-09 2 views
3

Все больше функций Python переходят в «ленивый исполняемый файл», например, генератор и другие итераторы. Иногда, однако, я вижу, что хочу бросить петлю «за», чтобы выполнить какое-то действие.Что такое самый питонический способ выполнения выражения генератора?

Какова была бы самая пифоническая вещь, чтобы получить цикл, фактически выполненный?

Например:

a = open("numbers.txt", "w") 
(a.write ("%d " % i) for i in xrange(100)) 
a.close() 

Не actuall код, но вы видите, что я имею в виду. Если я использую генератор списков, вместо этого у меня есть побочный эффект создания списка N-длины, заполненного «Нет».

В настоящее время я использую выражение как аргумент в вызове «any» или «all». Но я хотел бы найти способ, который не будет зависеть от результата выражения, выполняемого в цикле: как «любое», так и «все» могут останавливаться в зависимости от выражения, которое оценивается.

Для ясности, эти способы, чтобы сделать это, что я уже знаю о, и каждый из них имеет свои недостатки:

[a.write ("%d " % i) for i in xrange(100))] 

any((a.write ("%d " % i) for i in xrange(100))) 

for item in (a.write ("%d " % i) for i in xrange(100)): pass 
+2

"N-образный список, заполненный монахинями.« –

+0

Просто уточнить: я редко использую подобные вещи в производственном кодексе - и, учитывая реакцию здесь, я, вероятно, полностью остановлюсь. Но мне нравится веселиться, накладывая однострочные вещи (хотя они неряшливы по своей природе) - есть где я пропустил это больше всего. Только вчера я прошел большую попытку, чтобы получить однострочный шрифт для метода списка рубинов 1.9.2 «chunck» (однострочная версия сосала - но одна дополнительная строка, объявляющая словарь перед тем, как «исполняемый генератор» дает Python что-то приятнее, чем вещь «chunck») – jsbueno

+0

@Nas: Остановить случайное обвинение людей в вещах, которые они не делали. –

ответ

5

Есть много accumulators, которые влияют на то, что они потребляют всю итерабельность, которую они выдают, например min или max, - но даже они не полностью игнорируют результаты, полученные в процессе (например, min и max будут вызывать исключение, если некоторые результатов - комплексные числа). Я не думаю, что есть встроенный аккумулятор, который делает именно то, что вы хотите - вы должны будешь писать (и добавить в ваш личный крошечной функции полезности) крошечная функцию полезности, такие как

def consume(iterable): 
    for item in iterable: pass 

Основная причина, я думаю, в том, что у Python есть оператор for, и вы должны использовать его, когда он подходит как перчатка (т. Е. Для случаев, которые вам нужны consume для ;-).

BTW, a.write возвращает None, который является falsish, так any будет на самом деле потребляют его (и a.writelines будет еще лучше!). Но я понимаю, что вы просто приводили это как пример ;-).

+0

На самом деле, есть * способы выполнить то, что задано без недостатка 'min/max', в одной строке и без создания списка len (N). Я нашел 3 (три) отличных способа после хорошей ночи сна - но, по словам Ферма (http://en.wikipedia.org/wiki/Fermat's_Last_Theorem) - «Это поле слишком узкое, чтобы содержать [ это поистине чудесное доказательство] ':-) –

+0

@ Нет, есть очевидные тупиковые способы, такие как '[x for x in iterable if False]' (делает пустой список) и аналогичные 'any (x и False для x в итерабельном) '(не делает никакого списка вообще) и' all (x или True для x в итерабельном) '- но (пока они отлично подходят в этом поле ;-), они все серьезно подходят для съемок. –

+0

@ Нет, ну ... можете свободно использовать основную «страницу» вместо поля. :-) – jsbueno

7

Если бы я хотел сделать этот конкретный пример, я написал бы

for i in xrange(100): a.write('%d ' % i) 

Если я часто нужно потреблять итератор для его эффекта, я бы определить

def for_effect(iterable): 
    for _ in iterable: 
     pass 
+0

Я думаю, что цикл for выглядит лучше на 2 строки. Нам нравятся промежутки пространства Python –

+0

Да, я обычно пишу это так, но OP, возможно, не знал об однострочной форме и специально просил об этом. –

10

Существует один очевидный способ сделать это, и именно так вы должны это делать. Нет никакого оправдания для того, чтобы сделать это умным способом.

a = open("numbers.txt", "w") 
for i in xrange(100): 
    a.write("%d " % i) 
d.close() 

исполнения Ленивого дает серьезное преимущество: он позволяет передавать последовательность в другую часть коды, без необходимости держать все вещи в памяти. Он предназначен для создания эффективных последовательностей в виде типов данных.

В этом случае вы не хотите ленивого исполнения. Вы хотите выполнить. Вы можете просто выполнить. С петлей for.