I want to add two items at a time to a list comprehension. One item is constant. How can this be achieved using only one for loop inside of a list comprehension, and no additional functions. Answers that do not use any import will be favored.
Take a look at at the following:
>>> mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF'
>>> sum([['^', char] for char in mystring.lower()], [])
['^', 'a', '^', 'b', '^', 'c', '^', 'e', '^', 'l', '^', 'k', '^', 'j', '^', 's', '^', 'd', '^', 'l', '^', 'h', '^', 'f', '^', 'w', '^', 'e', '^', 'h', '^', 's', '^', 'j', '^', 'd', '^', 'h', '^', 'f', '^', 'k', '^', 'h', '^', 'i', '^', 'u', '^', 'e', '^', 'h', '^', 'f', '^', 's', '^', 'd', '^', 'f']
I am trying to make a list with the character ^
prepended before each letter in lower case. In this example, you need to use sum
to flatten the list. However, my question is, if it is possible to make a flat list in the first place. The output above is the desired output.
As in, append something constantly before a variable that changes with each iteration of the for
loop. One cannot use two for
loops here, as that would be too simple, for example:
mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF'
print [item for x in mystring.lower() for item in ['^', x]]
If one does something like this:
>>> mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF'
>>> [['^', x] for x in mystring]
['^', 'a', '^', 'b', '^', 'c', '^', 'e', '^', 'l', '^', 'k', '^', 'j', '^', 's', '^', 'd', '^', 'l', '^', 'h', '^', 'f', '^', 'w', '^', 'e', '^', 'h', '^', 's', '^', 'j', '^', 'd', '^', 'h', '^', 'f', '^', 'k', '^', 'h', '^', 'i', '^', 'u', '^', 'e', '^', 'h', '^', 'f', '^', 's', '^', 'd', '^', 'f']
You get lists within lists. Thus, is there a way that you can append two items at a time in a list comprehension without have to use an addition for loop or an additional function like sum
? I ask this, because its something quite simple, yet I can't find a way to do it. If one tries to do the following:
>>> ['^', x for x in mystring.lower()]
File "<console>", line 1
['^', x for x in mystring.lower()]
^
SyntaxError: invalid syntax
The attempt gives a SyntaxError
. So, is what I'm asking impossible to do in Python? Using ()
gives me a list of tuples.
I've also tried using the splat
/unpacking
operator:
>>> [*['^', x] for x in mystring.lower()]
File "<console>", line 1
[*['^', x] for x in mystring.lower()]
^
SyntaxError: invalid syntax
But as above, this too is a syntax error. Sorry for this late edit, but I have tried the following:
import itertools
mystring = "HELLOWORLD"
print(list(itertools.chain.from_iterable(('^', x) for x in mystring.lower())))
But the above still required an import.
Using append() to tell Python that each new element should be added to the end is also unnecessary; we don't need to use append() in list comprehension. Instead, we are just defining the variable highest_paid_actors_birthyear and assigning the list comprehension result to that variable.
It is a smart and concise way of creating lists by iterating over an iterable object. Nested List Comprehensions are nothing but a list comprehension within another list comprehension which is quite similar to nested for loops.
Answer. Yes, an else clause can be used with an if in a list comprehension. The following code example shows the use of an else in a simple list comprehension.
You can use itertools.chain.from_iterable
, this is equivalent to that nested list comprehension version but slightly efficient(for large lists):
>>> from itertools import chain
>>> mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF'
>>> list(chain.from_iterable([['^', x] for x in mystring]))
['^', 'A', '^', 'B', '^', 'C', '^', 'E', '^', 'L', '^', 'K', '^', 'J', '^', 'S', '^', 'D', '^', 'L', '^', 'H', '^', 'F', '^', 'W', '^', 'E', '^', 'H', '^', 'S', '^', 'J', '^', 'D', '^', 'H', '^', 'F', '^', 'K', '^', 'H', '^', 'I', '^', 'U', '^', 'E', '^', 'H', '^', 'F', '^', 'S', '^', 'D', '^', 'F']
In Python 3.3+ you can also use yield from
in a generator function:
>>> mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF'
>>> def solve(strs):
... for x in strs:
... yield from ['^', x]
...
>>> list(solve(mystring))
['^', 'A', '^', 'B', '^', 'C', '^', 'E', '^', 'L', '^', 'K', '^', 'J', '^', 'S', '^', 'D', '^', 'L', '^', 'H', '^', 'F', '^', 'W', '^', 'E', '^', 'H', '^', 'S', '^', 'J', '^', 'D', '^', 'H', '^', 'F', '^', 'K', '^', 'H', '^', 'I', '^', 'U', '^', 'E', '^', 'H', '^', 'F', '^', 'S', '^', 'D', '^', 'F']
You can start with this:
print list( '^'.join(mystring.lower()) )
which gives:
['a', '^', 'b', '^', 'c', '^', ...]
So this would give the desired output:
l = list( '^'.join(mystring.lower()) )
l.insert(0, '^')
print l
And another way:
print [ y for x in zip(['^'] * len(mystring), mystring.lower()) for y in x ]
which gives:
['^', 'a', '^', 'b', '^', 'c', ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With