combining lists of strings, improve performance - python
I have been able to join strings as such:
string_right = list(range(1,100))
string_left = ['AAA','BBB', "CCC"]
combination = []
for i in headers_right:
merged1 = string_left[0] + ' ' + str(i)
merged2 = string_left[1] + ' ' + str(i)
merged3 = string_left[2] + ' ' + str(i)
combination.append(merged1)
combination.append(merged2)
combination.append(merged3)
Is there a more efficient way to do it? I would like to avoid the for loop.
I was thinking about something like zip or enumerate, but they seem to create tuples instead of concatenating strings.
The result should look like:
['AAA1','BBB1', "CCC1", 'AAA2','BBB2', "CCC2",...,'AAA100','BBB100', "CCC100"]
Thanks so much in advance!
You can use itertools.product for this, which essentially gives a cartesian product of the two lists, and then we take each element from that product, and join the two elements.
For example
In [2]: from itertools import product
In [1]: string_right = range(1,3)
...: string_left = ['AAA','BBB', "CCC"]
In [3]: list(product(string_left, string_right))
Out[3]: [('AAA', 1), ('AAA', 2), ('BBB', 1), ('BBB', 2), ('CCC', 1), ('CCC', 2)]
Also if we use this approach, we don't need to convert the range into a list, since itertools.product takes iterators as an input
from itertools import product
string_right = range(1,100)
string_left = ['AAA','BBB', "CCC"]
#Take cartesian product of the two lists, and join elements together of each tuple
print([ '{}{}'.format(j,i) for i,j in product(string_right,string_left)])
The output will be
['AAA1', 'BBB1', 'CCC1', 'AAA2', 'BBB2', 'CCC2', 'AAA3', 'BBB3', 'CCC3', 'AAA4', 'BBB4', 'CCC4', 'AAA5', 'BBB5', 'CCC5', 'AAA6', 'BBB6', 'CCC6', 'AAA7', 'BBB7', 'CCC7', 'AAA8', 'BBB8', 'CCC8', 'AAA9', 'BBB9', 'CCC9', 'AAA10', 'BBB10', 'CCC10', 'AAA11', 'BBB11', 'CCC11', 'AAA12', 'BBB12', 'CCC12', 'AAA13', 'BBB13', 'CCC13', 'AAA14', 'BBB14', 'CCC14', 'AAA15', 'BBB15', 'CCC15', 'AAA16', 'BBB16', 'CCC16', 'AAA17', 'BBB17', 'CCC17', 'AAA18', 'BBB18', 'CCC18', 'AAA19', 'BBB19', 'CCC19', 'AAA20', 'BBB20', 'CCC20', 'AAA21', 'BBB21', 'CCC21', 'AAA22', 'BBB22', 'CCC22', 'AAA23', 'BBB23', 'CCC23', 'AAA24', 'BBB24', 'CCC24', 'AAA25', 'BBB25', 'CCC25', 'AAA26', 'BBB26', 'CCC26', 'AAA27', 'BBB27', 'CCC27', 'AAA28', 'BBB28', 'CCC28', 'AAA29', 'BBB29', 'CCC29', 'AAA30', 'BBB30', 'CCC30', 'AAA31', 'BBB31', 'CCC31', 'AAA32', 'BBB32', 'CCC32', 'AAA33', 'BBB33', 'CCC33', 'AAA34', 'BBB34', 'CCC34', 'AAA35', 'BBB35', 'CCC35', 'AAA36', 'BBB36', 'CCC36', 'AAA37', 'BBB37', 'CCC37', 'AAA38', 'BBB38', 'CCC38', 'AAA39', 'BBB39', 'CCC39', 'AAA40', 'BBB40', 'CCC40', 'AAA41', 'BBB41', 'CCC41', 'AAA42', 'BBB42', 'CCC42', 'AAA43', 'BBB43', 'CCC43', 'AAA44', 'BBB44', 'CCC44', 'AAA45', 'BBB45', 'CCC45', 'AAA46', 'BBB46', 'CCC46', 'AAA47', 'BBB47', 'CCC47', 'AAA48', 'BBB48', 'CCC48', 'AAA49', 'BBB49', 'CCC49', 'AAA50', 'BBB50', 'CCC50', 'AAA51', 'BBB51', 'CCC51', 'AAA52', 'BBB52', 'CCC52', 'AAA53', 'BBB53', 'CCC53', 'AAA54', 'BBB54', 'CCC54', 'AAA55', 'BBB55', 'CCC55', 'AAA56', 'BBB56', 'CCC56', 'AAA57', 'BBB57', 'CCC57', 'AAA58', 'BBB58', 'CCC58', 'AAA59', 'BBB59', 'CCC59', 'AAA60', 'BBB60', 'CCC60', 'AAA61', 'BBB61', 'CCC61', 'AAA62', 'BBB62', 'CCC62', 'AAA63', 'BBB63', 'CCC63', 'AAA64', 'BBB64', 'CCC64', 'AAA65', 'BBB65', 'CCC65', 'AAA66', 'BBB66', 'CCC66', 'AAA67', 'BBB67', 'CCC67', 'AAA68', 'BBB68', 'CCC68', 'AAA69', 'BBB69', 'CCC69', 'AAA70', 'BBB70', 'CCC70', 'AAA71', 'BBB71', 'CCC71', 'AAA72', 'BBB72', 'CCC72', 'AAA73', 'BBB73', 'CCC73', 'AAA74', 'BBB74', 'CCC74', 'AAA75', 'BBB75', 'CCC75', 'AAA76', 'BBB76', 'CCC76', 'AAA77', 'BBB77', 'CCC77', 'AAA78', 'BBB78', 'CCC78', 'AAA79', 'BBB79', 'CCC79', 'AAA80', 'BBB80', 'CCC80', 'AAA81', 'BBB81', 'CCC81', 'AAA82', 'BBB82', 'CCC82', 'AAA83', 'BBB83', 'CCC83', 'AAA84', 'BBB84', 'CCC84', 'AAA85', 'BBB85', 'CCC85', 'AAA86', 'BBB86', 'CCC86', 'AAA87', 'BBB87', 'CCC87', 'AAA88', 'BBB88', 'CCC88', 'AAA89', 'BBB89', 'CCC89', 'AAA90', 'BBB90', 'CCC90', 'AAA91', 'BBB91', 'CCC91', 'AAA92', 'BBB92', 'CCC92', 'AAA93', 'BBB93', 'CCC93', 'AAA94', 'BBB94', 'CCC94', 'AAA95', 'BBB95', 'CCC95', 'AAA96', 'BBB96', 'CCC96', 'AAA97', 'BBB97', 'CCC97', 'AAA98', 'BBB98', 'CCC98', 'AAA99', 'BBB99', 'CCC99']
Related
Adding an element in a nested list based on condition
I was wondering if you could help me simplify my code or find an efficient method. I am given a nested array and I wish to add the second element based on the first nested item. [('dog','1'),('dog','2'),('cat',1'),('cat','2')] This will result in: [('dog','3'),('cat','3')] I would want the numbers to be strings instead of int type. Here is my code below: dddd=[] dddd=result_1_ce+result_2_ce+result_3_ce+result_4_ce #Sum all of the elements from a prior find dddd stores [('dog','1'),('dog','2'),('cat',1'),('cat','2')] newlist = [[int(element) if element.isdigit() else element for element in sub] for sub in dddd] grouped = dict() grouped.update((name,grouped.get(name,0)+value) for name,value in newlist) dddd = [*map(list,grouped.items())] #Of this manipulation display it in reverse order dddd=sorted(dddd,key=lambda x:x[1],reverse=True) X = [tuple(i) for i in dddd] print("Findings:",X)
This code work I am writing a comment where I change the code. dddd=result_1_ce+result_2_ce+result_3_ce+result_4_ce #Sum all of the elements from a prior find dddd stores [('dog','1'),('dog','2'),('cat',1'),('cat','2')] newlist = [[int(element) if element.isdigit() else element for element in sub] for sub in dddd] grouped = dict() grouped.update((name,grouped.get(name,0)+value) for name,value in newlist) dddd = [*map(list,grouped.items())] #Of this manipulation display it in reverse order dddd=sorted(dddd,key=lambda x:x[1],reverse=True) X = [tuple([f,str(s)]) for f,s in dddd] # get two both element from the list of list and change second('s) element to str. print("Findings:",X) OUTPUT Findings: [('dog', '3'), ('cat', '3')] You dddd list is looks like this [['dog', 3], ['cat', 3]]. # If I write This dddd = [['dog', 3], ['cat', 3]] for f,s in dddd: # (f is for 'dog' and 'cat) and (s is for 3 and 3) print(f) print(s)
It seems to me, a very simple approach would be to convert to a dictionary first, and it is a good data structure for grouping. Also, use an integer to sum the numbers. You can use int of str if you are unsure if each number value will be int or str. Then to get the output of list of tuples, you just convert with a simple comprehension. l = [("dog", "1"), ("dog", "2"), ("cat", 1), ("cat", "2")] d = {} for t in l: d[t[0]] = d.setdefault(t[0], 0) + int(str(t[1])) print([(k, str(v)) for k, v in d.items()]) Output: [('dog', '3'), ('cat', '3')]
Python - list + tuples length of elements
I'm having some issues trying to figure this out (as i'm a pure beginner to python). I have a list of names: names_2 = ["Lars", "Per", "Henrik"] Which I need to convert into a tuple who hold each elements length + the element it self. I tried this: namesTuple = tuple(names_2 + [len(name) for name in names_2]) Output of this is: ('Lars', 'Per', 'Henrik', 4, 3, 6) The output im looking for is ('Lars', 4, 'Per', 3, 'Henrik', 6) Anyone who can help?
You can use a nested generator expression in the tuple constructor, for instance: names_tuple = tuple(x for name in names_2 for x in (name, len(name))) # ('Lars', 4, 'Per', 3, 'Henrik', 6) If you were to build it in a looping approach, it makes sense to build a list first (tuples are immutable): names = [] for name in names_2: # extend (both at once) names.extend((name, len(name))) # OR append one by one (no spurious intermediate tuple) # names.append(name) # names.append(len(name)) names_tuple = tuple(names)
names_2 = ["Lars", "Per", "Henrik"] names = [] for name in names_2: names.append(name) names.append(len(name)) names = tuple(names) Iterate over the names, append the name itself and its length to a list, and convert the list to tuple. Or as a one-liner (but you'll end up with a tuple of tuples): names_2 = ["Lars", "Per", "Henrik"] names = tuple((name, len(name)) for name in names_2)
Zip the list of names with the list of lengths, then flatten the resulting list and convert that to a tuple. from itertools import chain namesTuple = tuple(chain.from_iterable(zip(names_2, map(len, names_2)))) If you prefer something a little less "functional", you can use a generator expression. namesTuple = tuple(chain.from_iterable((x, len(x)) for x in names_2)) or (repeating #schwobaseggl's answer) namesTuple = tuple(value for name in names_2 for value in (name, len(name)))
First create a tuple of tuples : ((name_1,lenght_1), (name_2,lenght_2),...) The zip function is existing for that. Secondly, you have to flatten this tuple of tuples. [In] names = ["Lars", "Per", "Henrik"] [In] zip_tupled = tuple(zip(names, [len(x) for x in names])) [Out] zip_tupled = (('Lars', 4), ('Per', 3), ('Henrik', 6)) [In] final = tuple(item for subtuple in zip_tupled for item in subtuple) [Out] final = ('Lars', 4, 'Per', 3, 'Henrik', 6) This solution is quite close to the solution of schwobaseggl...But less direct/straight. Stackoverflow : how to flatten a list
concatenate 2d list with list comprehension instead of a for loop
Hi I have a 2d list that has 3 elements I have concatenated some of the elements using the following code list1 = [(1,"hello",3),(1,"excelent",4),(2,"marvelous",3)] length = len(list1) text = '' for irow in range(length): number = list1[irow][0] listText = list1[irow][1] ids = list1[irow][2] text += "<tag id = "+ str(ids)+">"+str(listText)+"<\\tag>\r\n" print(text) and this produces the following output <tag id = 3>hello<\tag> <tag id = 4>excelent<\tag> <tag id =3>marvelous<\tag> and this is correct, my question is there a way to do this using list comprehension, or is there a more pythonic way of achieving this same outcome.
You could reduce the whole thing to a one-liner, but I suggest that a reasonable compromise is probably still to use a for loop over your list, but in the for loop target you can unpack the sublists directly into the relevant variables. In any case there is no need for looping over index rather than the actual contents of list1. Using an f-string (in recent Python versions) will also help tidy things up. list1 = [(1,"hello",3),(1,"excelent",4),(2,"marvelous",3)] text = '' for number, listText, ids in list1: text += f'<tag id = {ids}>{listText}<\\tag>\r\n' print(text) You could also consider using the conventional dummy variable _ in place of number here, because you are not actually using the value: for _, listText, ids in list1:
Using list-comprehension: ee = [(1,"hello",3),(1,"excelent",4),(2,"marvelous",3)] print(["<tag id = "+ str(x[2])+">"+str(x[1])+"<\tag>" for x in ee]) OUTPUT: ['<tag id = 3>hello<\tag>', '<tag id = 4>excelent<\tag>', '<tag id = 3>marvelous<\tag>'] Edit: If you want to have the double quotes in the tags text: print(["<tag id = " + str(x[2])+" >" + str('"' + x[1] + '"') + "<\tag>" for x in ee]) OUTPUT: ['<tag id = 3 >"hello"<\tag>', '<tag id = 4 >"excelent"<\tag>', '<tag id = 3 >"marvelous"<\tag>']
Using f-strings and unpacking the tuple elements in the list comprehension makes this neatly readable: list1 = [ (1, "hello", 3), (1, "excelent", 4), (2, "marvelous", 3), ] texts = [ f'<tag id="{ids}">{text}<\\tag>' # TODO: handle HTML quoting? for (number, text, ids) in list1 ] text = "\r\n".join(texts)
iterate lambda function and use map() list1 = [(1, "hello", 3), (1, "excelent", 4), (2, "marvelous", 3)] text = map(lambda x: f'<tag id = {x[2]}>{x[1]}<\\tag>', list1) print('\r\n'.join(list(text)))
print list of tuples without brackets python
I have a list of tuples and I want to print flattened form of this list. I don't want to transform the list, just print it without parenthesis and brackets. input: [ ("a", 1), ("b",2), ("c", 3)] output: a 1 b 2 c 3 Here's what I do: l = [ ("a", 1), ("b",2), ("c", 3)] f = lambda x: " ".join(map(str,x)) print " ".join(f(x) for x in l) I'm interested in if anybody has a more elegant and possibly a more efficient solution,possibly without doing join, only print. Thanks in advance.
from __future__ import print_function l = [("a", 1), ("b",2), ("c", 3)] print(*(i for j in l for i in j)) a 1 b 2 c 3 Or using itertools.chain to flatten: from itertools import chain print(*chain(*l))
Using str.join() you can use a nested list comprehension: >>> print ' '.join([str(i) if isinstance(i,int) else i for tup in A for i in tup]) a 1 b 2 c 3 And without join() still you need to loop over the the items and concatenate them, which I think join() is more pythonic way for this aim.
If you absolutely have to do this without list flattening operations like join, then this will work, but it's terrible and you should just use join: [sys.stdout.write(str(i) + ' ' + str(j) + ' ') for (i, j) in input] Using stdout.write because it does not automatically append a newline like print does.
That's more simple than you can imagine. a = [ ("a", 1), ("b",2), ("c", 3)] for i,j in a: print(i,j,end=' ')
Format and print list of tuples as one line
I have a list containing tuples that is generated from a database query and it looks something like this. [(item1, value1), (item2, value2), (item3, value3),...] The tuple will be mixed length and when I print the output it will look like this. item1=value1, item2=value2, item3=value3,... I have looked for a while to try to find a solution and none of the .join() solutions I have found work for this type of situation.
You're after something like: >>> a = [('val', 1), ('val2', 2), ('val3', 3)] >>> ', '.join('{}={}'.format(*el) for el in a) 'val=1, val2=2, val3=3' This also doesn't care what type the tuple elements are... you'll get the str representation of them automatically.
You can use itertools as well from itertools import starmap ', '.join(starmap('{}={}'.format, a))
If each tuple is only an (item, value) pair then this should work: l = [(item1, value1), (item2, value2), (item3, value3), ...] ', '.join('='.join(t) for t in l) 'item1=value1, item2=value2, item3=value3, ...'
Try this: lst = [('item1', 'value1'), ('item2', 'value2'), ('item3', 'value3')] print ', '.join(str(x) + '=' + str(y) for x, y in lst) I'm explicitly converting to string the items and values, if one (or both) are already strings you can remove the corresponding str() conversion: print ', '.join(x + '=' + y for x, y in lst)
One possible solution is this, definitely the shortest code >>> a = [('val', 1), ('val2', 2), ('val3', 3)] >>>', '.join('%s=%s' % v for v in a) 'val=1, val2=2, val3=3' works with python 2.7 as well
If you want something like that, I would use a dictionary. dict = {1:2,3:4} print dict Then, you can loop through it like this: dict = {1:2,3:3} print dict for i in dict: print i, "=", dict[i] Hope it helps!