This question already has answers here:
Joining pairs of elements of a list [duplicate]
(7 answers)
Closed 2 years ago.
I have a list like
myl = ['A','B','C','D','E','F'] #length always even
Now my desired output is 'AB','CD','EF'
I tried
>>> myl = ['A','B','C','D','E','F']
>>> even_pos = myl[::2]
>>> odd_pos = myl[::-2]
>>> odd_pos.reverse()
>>> newlist = zip(even_pos,odd_pos)
>>> for x in newlist:
... print "".join(list(x))
...
...
AB
CD
EF
>>>
I don't like this way because I think this is too much.
So, is there any better way to achieve my output.
You can do this concisely using a list comprehension or generator expression:
>>> myl = ['A','B','C','D','E','F']
>>> [''.join(myl[i:i+2]) for i in range(0, len(myl), 2)]
['AB', 'CD', 'EF']
>>> print '\n'.join(''.join(myl[i:i+2]) for i in range(0, len(myl), 2))
AB
CD
EF
You could replace ''.join(myl[i:i+2]) with myl[i] + myl[i+1] for this particular case, but using the ''.join() method is easier for when you want to do groups of three or more.
Or an alternative that comes from the documentation for zip():
>>> map(''.join, zip(*[iter(myl)]*2))
['AB', 'CD', 'EF']
Why is your method so complicated? You could do basically what you did, but in one line, like so:
[ "".join(t) for t in zip(myl[::2], myl[1::2]) ]
F.J's answer is more efficient though.
How about this?
>>> ["%s%s" % (myl[c], myl[c+1]) for c in range(0, 6, 2)]
['AB', 'CD', 'EF']
I'd probably write:
[myl[i] + myl[i + 1] for i in xrange(len(myl), step=2)]
You could do:
myl = ['A','B','C','D','E','F']
[''.join(myl[i:i+2]) for i in range(0, len(myl), 2)]
print '\n'.join(''.join(myl[i:i+2]) for i in range(0, len(myl), 2))
Related
I have a string, list1 that I'm converting to a list in order to compare it with another list, list2, to find common elements.
The following code works, but I need to replace ' with " in the final output, since it will be used in TOML front matter.
list1 = "a b c"
list1 = list1.split(" ")
print list1
>>> ['a','b','c']
list2 = ["b"]
print list(set(list1).intersection(list2))
>>> ['b']
**I need ["b"]**
New to python. I've tried using replace() and searched around, but can't find a way to do so. Thanks in advance.
I'm using Python 2.7.
Like any other structured text format, use a proper library to generate TOML values. For example
>>> import toml
>>> list1 = "a b c"
>>> list1 = list1.split(" ")
>>> list2 = ["b"]
>>> v = list(set(list1).intersection(list2))
>>> print(v)
['b']
>>> print(toml.dumps({"values": v}))
values = [ "b",]
made it
import json
l1 = "a b c"
l1 = l1.split(" ")
print(l1)
l2 = ["b"]
print(json.dumps(list(set(l1).intersection(l2))))
print(type(l1))
output:
['a', 'b', 'c']
["b"]
<type 'list'>
This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 7 years ago.
I want to convert multiple lists inside a list? I am doing it with a loop, but each sub list item doesn't get a comma between it.
myList = [['a','b','c','d'],['a','b','c','d']]
myString = ''
for x in myList:
myString += ",".join(x)
print myString
ouput:
a,b,c,da,b,c,d
desired output:
a,b,c,d,a,b,c,d
This can be done using a list comprehension where you will "flatten" your list of lists in to a single list, and then use the "join" method to make your list a string. The ',' portion indicates to separate each part by a comma.
','.join([item for sub_list in myList for item in sub_list])
Note: Please look at my analysis below for what was tested to be the fastest solution on others proposed here
Demo:
myList = [['a','b','c','d'],['a','b','c','d']]
result = ','.join([item for sub_list in myList for item in sub_list])
output of result -> a,b,c,d,a,b,c,d
However, to further explode this in to parts to explain how this works, we can see the following example:
# create a new list called my_new_list
my_new_list = []
# Next we want to iterate over the outer list
for sub_list in myList:
# Now go over each item of the sublist
for item in sub_list:
# append it to our new list
my_new_list.append(item)
So at this point, outputting my_new_list will yield:
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd']
So, now all we have to do with this is make it a string. This is where the ','.join() comes in to play. We simply make this call:
myString = ','.join(my_new_list)
Outputting that will give us:
a,b,c,d,a,b,c,d
Further Analysis
So, looking at this further, it really piqued my interest. I suspect that in fact the other solutions are possibly faster. Therefore, why not test it!
I took each of the solutions proposed, and ran a timer against them with a much bigger sample set to see what would happen. Running the code yielded the following results in increasing order:
map: 3.8023074030061252
chain: 7.675725881999824
comprehension: 8.73164687899407
So, the clear winner here is in fact the map implementation. If anyone is interested, here is the code used to time the results:
from timeit import Timer
def comprehension(l):
return ','.join([i for sub_list in l for i in sub_list])
def chain(l):
from itertools import chain
return ','.join(chain.from_iterable(l))
def a_map(l):
return ','.join(map(','.join, l))
myList = [[str(i) for i in range(10)] for j in range(10)]
print(Timer(lambda: comprehension(myList)).timeit())
print(Timer(lambda: chain(myList)).timeit())
print(Timer(lambda: a_map(myList)).timeit())
from itertools import chain
myList = [['a','b','c','d'],['a','b','c','d']]
print(','.join(chain.from_iterable(myList)))
a,b,c,d,a,b,c,d
You could also just join at both levels:
>>> ','.join(map(','.join, myList))
'a,b,c,d,a,b,c,d'
It's shorter and significantly faster than the other solutions:
>>> myList = [['a'] * 1000] * 1000
>>> from timeit import timeit
>>> timeit(lambda: ','.join(map(','.join, myList)), number=10)
0.18380278121490046
>>> from itertools import chain
>>> timeit(lambda: ','.join(chain.from_iterable(myList)), number=10)
0.6535200733309843
>>> timeit(lambda: ','.join([item for sub_list in myList for item in sub_list]), number=10)
1.0301431917067738
I also tried [['a'] * 10] * 10, [['a'] * 10] * 100000 and [['a'] * 100000] * 10 and it was always the same picture.
myList = [['a','b','c','d'],[a','b','c','d']]
smyList = myList[0] + myList[1]
str1 = ','.join(str(x) for x in smyList)
print str1
output
a,b,c,d,a,b,c,d
If I apply this regex:
re.split(r"(^[^aeiou]+)(?=[aeiouy])", "janu")
on the string "janu", it gives the following result: ['', 'j', 'anu']
Now I want to apply this regex on the following list to get the similar results for each item as above. Can a for loop be used, and if yes, how?
lista = ['janu', 'manu', 'tanu', 'banu']
You can use a list comprehension:
>>> from re import split
>>> lista = ['janu', 'manu', 'tanu', 'banu']
>>> [split("(^[^aeiou]+)(?=[aeiouy])", x)[1]+"doc" for x in lista]
['jdoc', 'mdoc', 'tdoc', 'bdoc']
>>>
Edit regarding comment:
This will work:
>>> from re import split
>>> lista = ['janu', 'manu', 'tanu', 'banu']
>>> listb = []
>>> for item in lista:
... data = split("(^[^aeiou]+)(?=[aeiouy])", item)
... listb.append(data[2]+data[1]+"doc")
...
>>> listb
['anujdoc', 'anumdoc', 'anutdoc', 'anubdoc']
>>>
Use the list comprehension
[re.split(r"(^[^aeiou]+)(?=[aeiouy])", i) for i in list]
You can use a for loop but this is considered the pythonic way to do things.
Let's say I have two lists of strings:
a = ['####/boo', '####/baa', '####/bee', '####/bii', '####/buu']
where #### represents 4-digit random number. And
b = ['boo', 'aaa', 'bii']
I need to know which string entry in list a contains any given entry in b. I was able to accomplish this by couple of nested loops and then using the in operator for checking the string contains the current entry in b. But, being relatively new to py, I'm almost positive this was not the most pythonic or elegant way to write it. So, is there such idiom to reduce my solution?
The following code gives you an array with the indexes of a where the part after the slash is an element from b.
a_sep = [x.split('/')[1] for x in a]
idxs = [i for i, x in enumerate(a_sep) if x in b]
To improve performance, make b a set instead of a list.
Demo:
>>> a = ['####/boo', '####/baa', '####/bee', '####/bii', '####/buu']
>>> b = ['boo', 'aaa', 'bii']
>>> a_sep = [x.split('/')[1] for x in a]
>>> idxs = [i for i, x in enumerate(a_sep) if x in b]
>>> idxs
[0, 3]
>>> [a[i] for i in idxs]
['####/boo', '####/bii']
If you prefer to get the elements directly instead of the indexes:
>>> a = ['####/boo', '####/baa', '####/bee', '####/bii', '####/buu']
>>> b = ['boo', 'aaa', 'bii']
>>> [x for x in a if x.split('/')[1] in b]
['####/boo', '####/bii']
ThiefMaster's answer is good, and mine will be quite similar, but if you don't need to know the indexes, you can take a shortcut:
>>> a = ['####/boo', '####/baa', '####/bee', '####/bii', '####/buu']
>>> b = ['boo', 'aaa', 'bii']
>>> [x for x in a if x.split('/')[1] in b]
['####/boo', '####/bii']
Again, if b is a set, that will improve performance for large numbers of elements.
import random
a=[str(random.randint(1000,9999))+'/'+e for e in ['boo','baa','bee','bii','buu']]
b = ['boo', 'aaa', 'bii']
c=[x.split('/')[-1] for x in a if x.split('/')[-1] in b]
print c
prints:
['boo', 'bii']
Or, if you want the entire entry:
print [x for x in a if x.split('/')[-1] in b]
prints:
['3768/boo', '9110/bii']
>>> [i for i in a for j in b if j in i]
['####/boo', '####/bii']
This should do what you want, elegant and pythonic.
As other answers have indicated, you can use set operations to make this faster. Here's a way to do this:
>>> a_dict = dict((item.split('/')[1], item) for item in a)
>>> common = set(a_dict) & set(b)
>>> [a_dict[i] for i in common]
['####/boo', '####/bii']
I have got a list i.e.
ls= [u'Cancer',u"Men's",u'Orthopedics',u'Pediatric',u"Senior's",u"Women's"]
ls.sort() does not seem to work here due to presence of single quote in the list elements.
I need to sort this list. Any idea???
Actually, the question is valid and the answer is not exactly correct in general case.
If the test material was not already sorted, it would not get correctly alphabetized but the 's would cause the list to be sorted to wrong order:
>>> l = ["'''b", "a", "a'ab", "aaa"]
>>> l.sort()
>>> l
["'''b", 'a', "a'ab", 'aaa']
>>> from functools import partial
>>> import string
>>> keyfunc = partial(string.replace, old="'", new="")
>>> l.sort(key=keyfunc)
>>> l
['a', 'aaa', "a'ab", "'''b"]
>>> ls
[u'Cancer', u"Men's", u'Orthopedics', u'Pediatric', u"Senior's", u"Women's"]
>>> ls.sort()
>>> ls
[u'Cancer', u"Men's", u'Orthopedics', u'Pediatric', u"Senior's", u"Women's"]
Since the list was sorted in the first place, it didn't change. sort has no problem with ' - but note that it sorts before the a-z and A-Z characters:
>>> ls
[u'abc', u'abz', u"ab'"]
>>> ls.sort()
>>> ls
[u"ab'", u'abc', u'abz']
>>>