Несколько операторов в списке compherensions в Python?

Когда вы делаете vaTest(s1 + " 1 ");, строковое представление s1 будет использоваться из-за правил конкатенации строк (знак «+»). Поэтому вместо отформатированного массива вы получите что-то вроде: [Ljava.lang.String;@2a139a55

Замените его на vaTest(Arrays.toString(s1) + " 1 ");, чтобы получить ожидаемый результат.

10
задан hlovdal 26 December 2010 в 20:03
поделиться

9 ответов

Statements cannot go inside of expressions in Python; it was a complication that was deliberately designed out of the language. For this problem, try using a complication that did make it into the language: generators. Watch:

def total_and_item(sequence):
    total = 0
    for i in sequence:
        total += i
        yield (total, i)

list2 = list(total_and_item(list1))

The generator keeps a running tally of the items seen so far, and prefixes it to each item, just like it looks like you example tries to do. Of course, a straightforward loop might be even simpler, that creates an empty list at the top and just calls append() a lot! :-)

27
ответ дан 3 December 2019 в 14:00
поделиться

Вот пример из другого вопроса :

2
ответ дан 3 December 2019 в 14:00
поделиться

Print is a weird thing to call in a list comprehension. It'd help if you showed us what output you want, not just the code that doesn't work.

Here are two guesses for you. Either way, the important point is that the value statement in a list comprehension has to be a single value. You can't insert multiple items all at once. (If that's what you're trying to do, skip to the 2nd example.)

list1 = [1, 2, 3]
list2 = [(i, i*2, i) for i in list1]
# list2 = [(1, 2, 1), (2, 4, 2), (3, 6, 3)]

To get a flat list:

list1 = [1, 2, 3]
tmp = [(i, i*2) for i in list1]
list2 = []
map(list2.extend, tmp)
# list2 = [1, 2, 1, 2, 4, 2, 3, 6, 3]

Edit: Incrementing a value in the middle of the list comprehension is still weird. If you really need to do it, you're better off just writing a regular for loop, and appending values as you go. In Python, cleverness like that is almost always branded as "unpythonic." Do it if you must, but you will get no end of flak in forums like this. ;)

1
ответ дан 3 December 2019 в 14:00
поделиться

Я не совсем уверен, что вы пытаетесь сделать, но это, вероятно, что-то вроде

list2 = [(i, i*2, i) for i in list1]
print list2

Утверждение в понимании списка должно быть одно утверждение, но вы всегда можете сделать это вызовом функции:

def foo(i):
    print i
    print i * 2
    return i
list2 = [foo(i) for i in list1]
3
ответ дан 3 December 2019 в 14:00
поделиться

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

>>> list1 = (1,2,3,4)
>>> list2 = [(i, i*2) for i in list1] # Notice the braces around both items
>>> print(list2)
[(1, 2), (2, 4), (3, 6), (4, 8)]
1
ответ дан 3 December 2019 в 14:00
поделиться

For your edited example:

currentValue += sum(list1)

or:

for x in list1:
    currentValue += x

List comprehensions are great, I love them, but there's nothing wrong with the humble for loop and you shouldn't be afraid to use it :-)

EDIT: "But what if I wanna increment different than the collected values?"

Well, what do you want to increment by? You have the entire power of python at your command!

Increment by x-squared?

for x in list1:
    currentValue += x**2

Increment by some function of x and its position in the list?

for i, x in enumerate(list1):
    currentValue += i*x
1
ответ дан 3 December 2019 в 14:00
поделиться

You can't do multiple statements, but you can do a function call. To do what you seem to want above, you could do:

list1 = ...
list2 = [ (sum(list1[:i], i) for i in list1 ]

in general, since list comprehensions are part of the 'functional' part of python, you're restricted to... functions. Other folks have suggested that you could write your own functions if necessary, and that's also a valid suggestion.

0
ответ дан 3 December 2019 в 14:00
поделиться

Why would you create a duplicate list. It seems like all that list comprehension would do is just sum the contents.

Why not just.

list2 = list(list1)   #this makes a copy
currentValue = sum(list2)
1
ответ дан 3 December 2019 в 14:00
поделиться

Как сказал pjz, вы можете использовать функции, поэтому здесь вы можете использовать замыкание для отслеживания значения счетчика:

# defines a closure to enclose the sum variable
def make_counter(init_value=0):
    sum = [init_value]
    def inc(x=0):
        sum[0] += x
        return sum[0]
    return inc

Затем вы делаете то, что хотите, с помощью list1:

list1 = range(5)  # list1 = [0, 1, 2, 3, 4]

И теперь всего с двумя строками мы get list2:

counter = make_counter(10)  # counter with initial value of 10
list2 = reduce(operator.add, ([counter(x), x] for x in list1))

В конце список2 содержит:

[10, 0, 11, 1, 13, 2, 16, 3, 20, 4]

, что вы хотели, и вы можете получить значение счетчика после цикла с помощью одного вызова:

counter()  # value is 20

Наконец, вы можете заменить закрывающий материал на любая операция, которую вы хотите, здесь у нас есть приращение, но это действительно зависит от вас. Также обратите внимание, что мы используем сокращение до сглаживания списка2, и этот небольшой трюк требует, чтобы вы импортировали оператор перед вызовом строки с сокращением:

import operator
2
ответ дан 3 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: