I have two strings:
a ='hellowww'
b ='world'
Expected Output
c = 'hweolrllodwww'
My code:
for x,y in zip(a,b):
print(x,y)
Its not working in my case.
Note : Length of two strings ,may not be same.
zip stops when the shortest iterable is traversed. You can use itertool module instead via chain and zip_longest:
from itertools import chain, zip_longest
res = ''.join(chain.from_iterable(zip_longest(a, b, fillvalue='')))
# 'hweolrllodwww'
Related
I'm trying to create a list from a permutation of a str object. However the resultant list has duplicates. I have the following code:
from itertools import permutations
a = permutations('144')
b = [''.join(i) for i in a]
print(b)
What am I doing wrong? I'm getting the following:
['144', '144', '414', '441', '414', '441']
No. That is the expected result because there are duplicate characters in your input string.
If all you are interested are the elements of the permutation then pass your list through set. If instead you NEED a list, pass it through list again
Example:
from itertools import permutations
a = permutations('144')
b = set(''.join(i) for i in a)
c = list(set(''.join(i) for i in a)) # note that I've removed square brackets
print(b)
print(c)
Protip: use generator expressions wherever possible
You have duplicate elements (characters) in your string. The function permutations will not distinguish between them.
You will have no duplicates if you iterate the permutations of the set of the characters, e.g.:
from itertools import permutations
a = permutations(set('144'))
b = [''.join(i) for i in a]
print(b)
Or, if you want to iterate over the disctinct permutations of the string containing even duplicates of the same characters, you can use the set of the permutations, like:
from itertools import permutations
a = permutations('144')
b = [''.join(i) for i in set(a)]
print(b)
I have a list of dicts like so:
a = [ {'list':[1,2,3]}, {'list':[1,4,5]} ]
Am trying to get a flat set of the values in the list key like {1,2,3,4,5}. What's the quickest way?
You can write a loop like:
result = set()
for row in a:
result.update(row['list'])
which I think will work reasonably fast.
Or you can simply use set comprehension and that will result in the following one-liner:
result = {x for row in a for x in row['list']}
In case not all elements contain a 'list' key, you can use .get(..) with an empty tuple (this will reduce construction time):
result = {x for row in a for x in row.get('list',())}
It is not clear what your definition of "quickest" is, but whether it is speed or number of lines I would use a combination of itertools and a generator.
>>> import itertools
>>> a = [ {'list':[1,2,3]}, {'list':[1,4,5]} ]
>>> b = set(itertools.chain.from_iterable(x['list'] for x in a if 'list' in x))
Note that I have added a guard against any elements that may not contain a 'list' key; you can omit that if you know this will always be true.
flat list can be made through reduce easily.
All you need to use initializer - third argument in the reduce function.
reduce(
lambda _set, _dict, key='list': _set.update(
_dict.get(key) or set()) or _set,
a,
set())
Above code works for both python2 and python3, but you need to import reduce module as from functools import reduce. Refer below link for details.
for python2
for python3
So SO, i am trying to "merge" a string (a) and a list of strings (b):
a = '1234'
b = ['+', '-', '']
to get the desired output (c):
c = '1+2-34'
The characters in the desired output string alternate in terms of origin between string and list. Also, the list will always contain one element less than characters in the string. I was wondering what the fastest way to do this is.
what i have so far is the following:
c = a[0]
for i in range(len(b)):
c += b[i] + a[1:][i]
print(c) # prints -> 1+2-34
But i kind of feel like there is a better way to do this..
You can use itertools.zip_longest to zip the two sequences, then keep iterating even after the shorter sequence ran out of characters. If you run out of characters, you'll start getting None back, so just consume the rest of the numerical characters.
>>> from itertools import chain
>>> from itertools import zip_longest
>>> ''.join(i+j if j else i for i,j in zip_longest(a, b))
'1+2-34'
As #deceze suggested in the comments, you can also pass a fillvalue argument to zip_longest which will insert empty strings. I'd suggest his method since it's a bit more readable.
>>> ''.join(i+j for i,j in zip_longest(a, b, fillvalue=''))
'1+2-34'
A further optimization suggested by #ShadowRanger is to remove the temporary string concatenations (i+j) and replace those with an itertools.chain.from_iterable call instead
>>> ''.join(chain.from_iterable(zip_longest(a, b, fillvalue='')))
'1+2-34'
I have gone through Find intersection of two lists?, Intersection of Two Lists Of Strings, Getting intersection of two lists in python. However, I could not solve this problem of finding intersection between two string lists using Python.
I have two variables.
A = [['11#N3'], ['23#N0'], ['62#N0'], ['99#N0'], ['47#N7']]
B = [['23#N0'], ['12#N1']]
How to find that '23#N0' is a part of both A and B?
I tried using intersect(a,b) as mentioned in http://www.saltycrane.com/blog/2008/01/how-to-find-intersection-and-union-of/
But, when I try to convert A into set, it throws an error:
File "<stdin>", line 1, in <module> TypeError: unhashable type: 'list'
To convert this into a set, I used the method in TypeError: unhashable type: 'list' when using built-in set function where the list can be converted using
result = sorted(set(map(tuple, A)), reverse=True)
into a tuple and then the tuple can be converted into a set. However, this returns a null set as the intersection.
Can you help me find the intersection?
You can use flatten function of compiler.ast module to flatten your sub-list and then apply set intersection like this
from compiler.ast import flatten
A=[['11#N3'], ['23#N0'], ['62#N0'], ['99#N0'], ['47#N7']]
B=[['23#N0'], ['12#N1']]
a = flatten(A)
b = flatten(B)
common_elements = list(set(a).intersection(set(b)))
common_elements
['23#N0']
The problem is that your lists contain sublists so they cannot be converted to sets. Try this:
A=[['11#N3'], ['23#N0'], ['62#N0'], ['99#N0'], ['47#N7']]
B=[['23#N0'], ['12#N1']]
C = [item for sublist in A for item in sublist]
D = [item for sublist in B for item in sublist]
print set(C).intersection(set(D))
Your datastructure is a bit strange, as it is a list of one-element lists of strings; you'd want to reduce it to a list of strings, then you can apply the previous solutions:
Thus a list like:
B = [['23#N0'], ['12#N1']]
can be converted to iterator that iterates over '23#N0', '12#N1'
with itertools.chain(*), thus we have simple oneliner:
>>> set(chain(*A)).intersection(chain(*B))
{'23#N0'}
In case you have to fit it on a fortune cookie:
set(i[0] for i in A).intersection(set(i[0] for i in B))
You have two lists of lists with one item each. In order to convert that to a set you have to make it a list of strings:
set_a = set([i[0] for i in A])
set_b = set([i[0] for i in B])
Now you can get the intersection:
set_a.intersection(set_b)
A=[['11#N3'], ['23#N0'], ['62#N0'], ['99#N0'], ['47#N7']]
A=[a[0] for a in A]
B=[['23#N0'], ['12#N1']]
B=[b[0] for b in B]
print set.intersection(set(A),set(B))
Output:set(['23#N0'])
If each of your list has sublists of only 1 element you can try this.
My preference is to use itertools.chain from the standard library:
from itertools import chain
A = [['11#N3'], ['23#N0'], ['62#N0'], ['99#N0'], ['47#N7']]
B = [['23#N0'], ['12#N1']]
set(chain(*A)) & set(chain(*B))
# {'23#N0'}
I have a list of list, such as
T =[[0.10113], [0.56325], [0.02563], [0.09602], [0.06406], [0.04807]]
I would like to find the total sum of these numbers.
I am new to python programming, when I try a simple int(T[1]) conversion, I get error
TypeError: int() argument must be a string or a number, not 'list'
I appreciate any input.
easy:
sum(x[0] for x in T)
You're done :)
Of course, you could use
import itertools
sum(itertools.chain.from_iterable(T))
too. This would work if your sublists had more than 1 element each.
You can use map for this:
sum(map(sum, T))
>>> sum(map(sum, T))
0.89816000000000007
From the documentation for map:
map(function, iterable, ...)
Apply function to every item of iterable and return a list of the results.
So you are using map to total up the inner lists, and then a call to sum to total those values for the final answer.
This approach will work if your inner lists contain multiple items.
In [31]: T =[[0.10113], [0.56325], [0.02563], [0.09602], [0.06406], [0.04807]]
In [32]: sum(t[0] for t in T)
Out[32]: 0.8981600000000001
>>> T =[[0.10113], [0.56325], [0.02563], [0.09602], [0.06406], [0.04807]]
>>> sum(x[0] for x in T)
0.8981600000000001
You can use numpy sum module
import numpy as np
result = int(np.sum(T, axis=0))
or a inbuilt map function
result = int(sum(map(sum, T)))