I have a list of strings like
['ABC', 'DEF', 'GHIJ']
and I want a list of strings containing the first letter of each string, i.e.
['A', 'D', 'G'].
I thought about doing that using map and the function that returns the first element of a list: my_list[0]. But how can I pass this to map?
Thanks.
you can try
In [14]: l = ['ABC', 'DEF', 'GHIJ']
In [15]: [x[0] for x in l]
Out[15]: ['A', 'D', 'G']
You should use a list comprehension, like #avasal since it's more pythonic, but here's how to do it with map:
>>> from operator import itemgetter
>>> L = ['ABC', 'DEF', 'GHIJ']
>>> map(itemgetter(0), L)
['A', 'D', 'G']
use list comprehension like so:
results = [i[0] for i in mySrcList]
One way:
l1=['ABC', 'DEF', 'GHIJ']
l1=map(lambda x:x[0], l1)
a=['ABC','DEF','GHI']
b=[]
for i in a:
b.append(i[0])
b is the array you need.
Try this.
>>> myArray=['ABC', 'DEF', 'GHIJ']
>>> newArray=[]
>>> for i in map(lambda x:x[0],myArray):
... newArray.append(i)
...
>>> print(newArray)
['A', 'D', 'G']
Related
Given the list ['a','ab','abc','bac'], I want to compute a list with strings that have 'ab' in them. I.e. the result is ['ab','abc']. How can this be done in Python?
This simple filtering can be achieved in many ways with Python. The best approach is to use "list comprehensions" as follows:
>>> lst = ['a', 'ab', 'abc', 'bac']
>>> [k for k in lst if 'ab' in k]
['ab', 'abc']
Another way is to use the filter function. In Python 2:
>>> filter(lambda k: 'ab' in k, lst)
['ab', 'abc']
In Python 3, it returns an iterator instead of a list, but you can cast it:
>>> list(filter(lambda k: 'ab' in k, lst))
['ab', 'abc']
Though it's better practice to use a comprehension.
[x for x in L if 'ab' in x]
# To support matches from the beginning, not any matches:
items = ['a', 'ab', 'abc', 'bac']
prefix = 'ab'
filter(lambda x: x.startswith(prefix), items)
Tried this out quickly in the interactive shell:
>>> l = ['a', 'ab', 'abc', 'bac']
>>> [x for x in l if 'ab' in x]
['ab', 'abc']
>>>
Why does this work? Because the in operator is defined for strings to mean: "is substring of".
Also, you might want to consider writing out the loop as opposed to using the list comprehension syntax used above:
l = ['a', 'ab', 'abc', 'bac']
result = []
for s in l:
if 'ab' in s:
result.append(s)
mylist = ['a', 'ab', 'abc']
assert 'ab' in mylist
I have a list ['a','b','c','d'], want to make another list, like this: ['a', 'ab', abc', 'abcd']?
Thanks
Tried:
list1=['a','b','c', 'd']
for i in range(1, (len(list1)+1)):
for j in range(1, 1+i):
print(*[list1[j-1]], end = "")
print()
returns:
a
ab
abc
abcd
It does print what i want, but not sure,how to add it to a list to look like ['a', 'ab', abc', 'abcd']
Use itertools.accumulate, which by default sums up the elements for accumulation like a cummulative sum. Since addition (__add__) is defined for str and results in the concatenation of the strings
assert "a" + "b" == "ab"
we can use accumulate as is:
import itertools
list1 = ["a", "b", "c", "d"]
list2 = list(itertools.accumulate(list1)) # list() because accumulate returns an iterator
print(list2) # ['a', 'ab', 'abc', 'abcd']
Append to a second list in a loop:
list1=['a','b','c', 'd']
list2 = []
s = ''
for c in list1:
s += c
list2.append(s)
print(list2)
Output:
['a', 'ab', 'abc', 'abcd']
list1=['a','b','c', 'd']
l = []
for i in range(len(list1)):
l.append("".join(list1[:i+1]))
print(l)
Printing stuff is useless if you want to do ANYTHING else with the data you are printing. Only use it when you actually want to display something to console.
You could form a string and slice it in a list comprehension:
s = ''.join(['a', 'b', 'c', 'd'])
out = [s[:i+1] for i, _ in enumerate(s)]
print(out):
['a', 'ab', 'abc', 'abcd']
You can do this in a list comprehension:
vals = ['a', 'b', 'c', 'd']
res = [''.join(vals[:i+1]) for i, _ in enumerate(vals)]
Code:
[''.join(list1[:i+1]) for i,l in enumerate(list1)]
Output:
['a', 'ab', 'abc', 'abcd']
a='sadfaad'
b=[]
b.append(x for x in a)
print(b)
It returns
[<generator object <genexpr> at 0x000002042A1DA5F0>]
What to know why it happens so? and how can we use list comprehension for it?
To get the actual result of the comprehension, you need to exhaust the generator by converting to list:
a='sadfaad'
b=[]
b.append([x for x in a])
print(b)
output: [['s', 'a', 'd', 'f', 'a', 'a', 'd']]
If you want to add the elements, use extend:
a='sadfaad'
b=[]
b.extend([x for x in a])
print(b)
output: ['s', 'a', 'd', 'f', 'a', 'a', 'd']
But, unless this is just a toy example, the best remains to convert without loop:
b = list(a)
print(b)
output: ['s', 'a', 'd', 'f', 'a', 'a', 'd']
You can also do a simple list comprehension like this:
a='sadfaad'
b = [x for x in a]
And that will return a list of characters in a
(x for x in a) # This will produce a generator that will yield x when called. Note '()' syntax
[x for x in a] # This will produce a list. Note the '[]' syntax
In fact, [x for x in a] can be thought of as a generator expression wrapped in a list constructor.
[x for x in a] is really the same as list(x for x in a)
I have an input list as follows:
test_list = ['a', ('abc', 'd'), ['efgh', 'i'], 'jkl']
which I need to flatten, so getting rid of the tuple and list as respective second and third element of test_list
Expected output:
['a', 'abc', 'd', 'efgh', 'i', 'jkl']
I have a problem finding the correct list comprehension for this.
I have tried the following 2 examples:
result = [xs if type(xs) is str else x for xs in test_list for x in xs]
print('result', result)
# this outputs:
# ['a', 'abc', 'd', 'efgh', 'i', 'jkl', 'jkl', 'jkl']
result = [x if ((type(xs) is list) or (type(xs) is tuple)) else xs for xs in test_list for x in xs]
print('result',result)
#this also outputs:
# ['a', 'abc', 'd', 'efgh', 'i', 'jkl', 'jkl', 'jkl']
as you can see, it does "flatten" the list, but it repeats the last element based on the number of characters in the last element. Example if the last element of the test_list is 'jklm' then the in the result the last element is repeated 4 times.
I would like to know if there is a list comprehension which flatten my input list to the expected output without repeating the last element.
The following nested comprehension will work:
[x for sub in test_list for x in (sub if isinstance(sub, (list, tuple)) else [sub])]
This uses isinstance which should preferred over type(...) and can be given multiple types. If any top level element is not a list or tuple, it is wrapped in a list.
You can try:
test_list = ['a', ('abc', 'd'), ['efgh', 'i'], 'jkl']
result = [x for xs in test_list for x in (xs if isinstance(xs, (tuple, list)) else [xs])]
But I wouldn't use this, I would just write a for loop
You could always convert all single elements in test_list to lists:
>>> test_list = ['a', ('abc', 'd'), ['efgh', 'i'], 'jkl']
>>> convert_to_lists = [[x] if not isinstance(x, (list, tuple)) else x for x in test_list]
>>> convert_to_lists
[['a'], ('abc', 'd'), ['efgh', 'i'], ['jkl']]
Then just flatten this with itertools.chain_from_iterable:
>>> from itertools import chain
>>> list(chain.from_iterable(convert_to_lists))
['a', 'abc', 'd', 'efgh', 'i', 'jkl']
or all in one line:
list(chain.from_iterable([x] if not isinstance(x, (list, tuple)) else x for x in test_list))
Using for loop and function for future use.
Added primitives instead of type.
Splitting at , which you can change according to your requirements
list_1 = ['a', ('abc', 'd'), ['efgh', 'i'], 'jkl', {2,2.5}]
def to_flatten(my_list, primitives=(bool, str, int, float)):
flatten = []
my_list = [stuff.split(',') if type(stuff) == str else stuff for stuff in list_1]
for item in my_list:
if isinstance(item, primitives):
flatten.append(item)
else:
flatten.extend(item)
return flatten
print(to_flatten(list_1))
gives
['a', 'abc', 'd', 'efgh', 'i', 'jkl', 2, 2.5]
[Program finished]
you can use join() method
>>> test_list = ['a', ('abc', 'd'), ['efgh', 'i'], 'jkl']
>>> ",".join([",".join(i) if type(i) in [list,tuple] else i for i in test_list]).split(",")
['a', 'abc', 'd', 'efgh', 'i', 'jkl']
>>>
I want to split a string like:
'aaabbccccabbb'
into
['aaa', 'bb', 'cccc', 'a', 'bbb']
What's an elegant way to do this in Python? If it makes it easier, it can be assumed that the string will only contain a's, b's and c's.
That is the use case for itertools.groupby :)
>>> from itertools import groupby
>>> s = 'aaabbccccabbb'
>>> [''.join(y) for _,y in groupby(s)]
['aaa', 'bb', 'cccc', 'a', 'bbb']
You can create an iterator - without trying to be smart just to keep it short and unreadable:
def yield_same(string):
it_str = iter(string)
result = it_str.next()
for next_chr in it_str:
if next_chr != result[0]:
yield result
result = ""
result += next_chr
yield result
..
>>> list(yield_same("aaaaaabcbcdcdccccccdddddd"))
['aaaaaa', 'b', 'c', 'b', 'c', 'd', 'c', 'd', 'cccccc', 'dddddd']
>>>
edit
ok, so there is itertools.groupby, which probably does something like this.
Here's the best way I could find using regex:
print [a for a,b in re.findall(r"((\w)\2*)", s)]
>>> import re
>>> s = 'aaabbccccabbb'
>>> [m.group() for m in re.finditer(r'(\w)(\1*)',s)]
['aaa', 'bb', 'cccc', 'a', 'bbb']