Python - list + tuples length of elements - python

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

Related

Modify tuples inside a list

I'm trying to make a bunch of tuples show only one decimal using a for loop.
Van = (500.3736434, 43.834434)
Vbn = (300.2321313, 64)
Vcn = (250.43513241, 12)
listap = [Van, Vbn, Vcn]
for i in range(0,len(listap)):
listap[i] = tuple([float("{0:.1f}".format(n)) for n in listap[i]])
The desired result is only displayed when I print a specific index in the list, like print(listap[0])for example. Anyway I can get the reduced tuples without using the list? for example, doing
print(Van)
>>> (500.4, 43.8)
Python tuples are immutable - you cannot modify them in place. What you could do is, instead to convert into the desired format and rename the converted variables to the same name -
Van, Vbn, Vcn = [tuple([float("{0:.1f}".format(n)) for n in el]) for el in listap]
print(Van)
# (500.4, 43.8)
You have to create a new tuple.
new_list = []
for old_tuple in listap:
new_tuple = tuple([round(i, 1) for i in old_tuple])
new_list.append(new_tuple)
print(new_list)
# [(500.4, 43.8), (300.2, 64), (250.4, 12)]
But, if you just want to print them as a list, you can do:
for old_tuple in listap:
print([round(i, 1) for i in old_tuple])
which outputs
[500.4, 43.8]
[300.2, 64]
[250.4, 12]

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')]

Convert a nested list from [[...],[...]] to [(...),(...)] [duplicate]

This question already has answers here:
How to sum up a list of tuples having the same first element?
(5 answers)
How to perform a groupby operation in Python on a list of tuples where we need to sum the second element? [duplicate]
(1 answer)
Closed 10 months ago.
Convert a nested list from [[...],[...]] to [(...),(...)]. I wish to format my list below :
x=[['dog', 2], ['bird', 1],['dog',1]]
to
x=[('dog', 3), ('bird', 1)]
Here is my code for reference.
#Convert last element of nested list to int
newlist = [[int(element) if element.isdigit() else element for element in sub for sub in x]
#add the 2 columns that match
grouped = dict()
grouped.update((name,grouped.get(name,0)+value) for name,value in newlist)
x = [*map(list,grouped.items())]
Could this be due to my use of a dict()
I have been successful with adding the second indices given that the first ones match, however the result is being formatted as such
x=[['dog', 3], ['bird', 1]]
however, I would like it as so any advice on how to get this ideal output?
x=[('dog', 3), ('bird', 1)]
I guess you are looking for collections.Counter:
from collections import Counter
x=[['dog', 2], ['bird', 1],['dog',1]]
c = Counter()
for k, v in x:
c[k] += v
print(c)
# as pointed out by wim in the comments, use the below
# to get a list of tuples:
print([*c.items()])
Here is one way to do so:
x = [['dog', 2], ['bird', 1], ['dog', 1]]
data = {k: 0 for k, _ in x}
for key, num in x:
data[key] += num
print(list(data.items())) # [('dog', 3), ('bird', 1)]
You can also use setdefault():
data = {}
for key, num in x:
data.setdefault(key, 0)
data[key] += num
print(list(data.items()))
looks like this works
newlist = [int(element) if element[0].isdigit() else element for element in [sub for sub in x]]
# add the 2 columns that match
grouped = dict()
grouped.update((name, grouped.get(name, 0) + value) for name, value in newlist)
x = [*map(tuple, grouped.items())]
Don't make it a list in the first place. The only real thing to note here is replacing list with tuple however, I also removed the unpacking ([*...]) and went directly to casting the parent as a list.
change:
x = [*map(list,grouped.items())]
to:
x = list(map(tuple, grouped.items()))
x=[['dog', 3], ['bird', 1]]
# You want it to be...
x=[('dog', 3), ('bird', 1)]
So you should first know how to convert ['dog', 3] to ('dog', 3):
>>> x = ['dog', 3]
>>> tuple(x)
('dog', 3)
To make it a tuple you just have to use the tuple's class constructor.
Then you have to apply this to the whole x list:
x = [tuple(i) for i in x]

Comparing two lists with specific values to read

I have two lists
list1 = ['01:15', 'abc', '01:15', 'def', '01:45', 'ghi' ]
list2 = ['01:15', 'abc', '01:15', 'uvz', '01:45', 'ghi' ]
and when I loop through the list
list_difference = []
for item in list1:
if item not in list2:
list_difference.append(item)
and I managed to get the difference, but I need time as well
because it is a separate item and 'uvz' does not mean to me anything in the list with a few thousand entries.
I tried to convert it to the dictionary, but it overwrites with the last key:value {'01:15' : 'def'}.
Convert the two lists to sets of tuples, then use the set difference operator.
set1 = set((list1[i], list1[i+1]) for i in range(0, len(list1), 2))
set2 = set((list2[i], list2[i+1]) for i in range(0, len(list2), 2))
list_difference = list(set1 - set2)
reformat your data, then do whatever you have done before
list1=list(zip(list1[::2],list1[1::2]))
list2=list(zip(list2[::2],list2[1::2]))

Remove duplicates from dictionary of tuples

I have the following dictionary, that consists of Keys: list of tuples as values
{0: [(1410.0, 21.77562368178597), (1400.0, 19.207664561646514), (1400.0, 0.0008002910625641847), (1390.0, 0.005384339399360756), (1390.0, 16.81119144715727), (1380.0, 0.006317587214078991), (1380.0, 14.581397723675186), (1370.0, 12.425676833176958), (1360.0, 10.157186391679849), (1350.0, 8.464056857473565), (1340.0, 6.743908971063571), (1330.0, 4.886783322196731), (1320.0, 3.712576730302521), (1310.0, 2.689847385668083), (1300.0, 1.6219146729959537), (1290.0, 0.41216337921204677)], ....etc)
In some cases there are tuples that have same first element but different second element.
In the example from the code above (1400, 19.2) & (1400, 0.0000000000291)
What I want to do is to combine these tuples into one tuple (1400, (sum of the second element)
Is this what you mean?
Suppose that d is the name of your dictionary.
d = {0: [(1410.0, 21.77562368178597), (1400.0, 19.207664561646514), (1400.0, 0.0008002910625641847), (1390.0, 0.005384339399360756), (1390.0, 16.81119144715727), (1380.0, 0.006317587214078991), (1380.0, 14.581397723675186), (1370.0, 12.425676833176958), (1360.0, 10.157186391679849), (1350.0, 8.464056857473565), (1340.0, 6.743908971063571), (1330.0, 4.886783322196731), (1320.0, 3.712576730302521), (1310.0, 2.689847385668083), (1300.0, 1.6219146729959537), (1290.0, 0.41216337921204677)]}
Now try this code:
new_d = {}
for item in d:
summations = {}
for key, value in d[item]:
if key in summations:
summations[key] += value
else:
summations[key] = value
temp_list = []
for key in summations:
temp_list.append((key, summations[key]))
new_d[item] = temp_list
print(new_d)
first Idea that i got is 2 for loops in the first one you take the first number from the current tuple and in the second for loop you compare it to each first number of the elemet in the dic. If it matches than you take the second number from that element from that tuple and add it to the one from the first for loop.Than you delete the tuple in the second loop.You could also save each key for all tuples that have duplicate first number and delate them in the next step There might be a better solution for this but this is what i would try if Performance is not important
s = set()
[s.add(t) for t in dict_of_tuples.values()]
Demo:
>>> dict_of_tuples = tuple([1,2,(3,3), (3, 3)]
{1, 2, (3, 3), (3,3)}
>>> s = set()
>>> [s.add(t) for t in dict_of_tuples.values()]
(1, 2, (3,3))

Categories

Resources