Python List Comprehension Loop Over Multiple Collections - python-3.x

Say I'm trying to generate a list like this using a comprehension:
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
I'm receiving an error "TypeError: 'bool' object is not iterable" when trying to do:
mylist = [(letter,num) for letter in 'abcd' and num in range(1,4)]
What am I missing?

This might help:
mylist = [letter for letter in zip('abcd' , range(1,5))]
Or If you want the length to be dynamic.
myString = "abcd"
lengthOfStr= len(myString )
mylist = [letter for letter in zip(myString , range(1,lengthOfStr))]
We here zip two iterables and zip itself return tuple.

You're missing quite a few things actually.
range(1,4) generates the following numbers : 1,2,3
why do you think you should connect the lists using "and"?
and finally, you are missing zip

Related

How to convert a 3 column tuple without header to a two key single value dictionary in python?

Suppose I have two tuples, say:
l = (water, lily , 6)
m = (history , book, 5)
I want to convert it to a dictionary with 2 keys and a single value.
dict = {(water,lily): 6} {(history, book) : 5}
for the multiple line tuples in python.
How would I accomplish that?
You can use list comprehension.
l = [('water', 'lily' , 6), ('history' , 'book', 5)]
x = {(one, two): three for one, two, three in l}
print(x) # Prints {('water', 'lilly'): 6, ('history', 'book'): 5)}

Converting a list that contains integers and strings into a nested tuple, Python [duplicate]

This question already has answers here:
Pairs from single list [duplicate]
(10 answers)
Closed 4 years ago.
I wish to convert a string into a nested tuple for instance:
string = 'Jane A 3 B- 3 F 1#Bob C+ 2 D+ 3#Chris C 4 C 3 C- 2'
As you can see, the string is not normal with # signs and white-spaces in place of a comma. The # sign is what represents the number of names for which I have to compute some data that follows after each name. So I used string.split('#') to create 3 separate strings and from there, I used a for loop to get this on the first iteration:
['A', 3, 'B-', 3, 'F', 1]
The reason why 'Jane' is missing from the list is because I only need to take the values, whether it be a string or an integer, and make a nested tuple out of them. Thus, I wish to convert this list into a nested tuple that looks like:
[('A', 3), ('B-', 3), ('F', 1)]
I will greatly appreciate any help or suggestions.
I dont know if there is a better way, but here we go:
input = ['A', 3, 'B-', 3, 'F', 1]
l1 = input[::2] # get even
l2 = input[1::2] # get odd
tuples = list(zip(l1,l2)) # zip them together
# yes it could be wrote `tuples = list(zip(input[::2],input[1::2]))`
print (tuples)
Output
[('A', 3), ('B-', 3), ('F', 1)]
Try it online!
using regular expressions
>>> import re
>>> [[(mark, int(count))
for mark, count in map(str.split,
re.findall(r'[A-Z][+-]? \d+', student_data))]
for student_data in string.split('#')]
[[('A', 3), ('B-', 3), ('F', 1)],
[('C+', 2), ('D+', 3)],
[('C', 4), ('C', 3), ('C-', 2)]]
Step-by-step explanation
We're separating students (let's call them so) from each other since we need to store their "marks" (or what does these A/B/C/D with +/- mean?) in different containers:
string.split('#')
For each student we're searching "mark" data using regular expression
[A-Z][+-]? \d+
which can be read like
any capital Latin letter (which optionally may be followed by + or - sign) and a whitespace followed by digits
and pass it and student's substring to re.findall function. After that we will have something like:
>>> [re.findall(r'[A-Z][+-]? \d', student_data) for student_data in string.split('#')]
[['A 3', 'B- 3', 'F 1'], ['C+ 2', 'D+ 3'], ['C 4', 'C 3', 'C- 2']]
Finally we can use str.split method to separate letters with +/- from digits and iterate over this pairs converting second coordinates to int.
Further reading
map built-in docs.
re module docs.

Python: How to find the average on each array in the list?

Lets say I have a list with three arrays as following:
[(1,2,0),(2,9,6),(2,3,6)]
Is it possible I get the average by diving each "slot" of the arrays in the list.
For example:
(1+2+2)/3, (2+0+9)/3, (0+6+6)/3
and make it become new arraylist with only 3 integers.
You can use zip to associate all of the elements in each of the interior tuples by index
tups = [(1,2,0),(2,9,6),(2,3,6)]
print([sum(x)/len(x) for x in zip(*tups)])
# [1.6666666666666667, 4.666666666666667, 4.0]
You can also do something like sum(x)//len(x) or round(sum(x)/len(x)) inside the list comprehension to get an integer.
Here are couple of ways you can do it.
data = [(1,2,0),(2,9,6),(2,3,6)]
avg_array = []
for tu in data:
avg_array.append(sum(tu)/len(tu))
print(avg_array)
using list comprehension
data = [(1,2,0),(2,9,6),(2,3,6)]
comp = [ sum(i)/len(i) for i in data]
print(comp)
Can be achieved by doing something like this.
Create an empty array. Loop through your current array and use the sum and len functions to calculate averages. Then append the average to your new array.
array = [(1,2,0),(2,9,6),(2,3,6)]
arraynew = []
for i in range(0,len(array)):
arraynew.append(sum(array[i]) / len(array[i]))
print arraynew
As you were told in the comments with sum and len it's pretty easy.
But in python I would do something like this, assuming you want to maintain decimal precision:
list = [(1, 2, 0), (2, 9, 6), (2, 3, 6)]
res = map(lambda l: round(float(sum(l)) / len(l), 2), list)
Output:
[1.0, 5.67, 3.67]
But as you said you wanted 3 ints in your question, would be like this:
res = map(lambda l: sum(l) / len(l), list)
Output:
[1, 5, 3]
Edit:
To sum the same index of each tuple, the most elegant method is the solution provided by #PatrickHaugh.
On the other hand, if you are not fond of list comprehensions and some built in functions as zip is, here's a little longer and less elegant version using a for loop:
arr = []
for i in range(0, len(list)):
arr.append(sum(l[i] for l in list) / len(list))
print(arr)
Output:
[1, 4, 4]

How to add a pair to a dictionary in python?

I created the following dictionary: d = {}
I add to it a new key and a couple as the corresponding d['Key1'] = (1, 2)
If I print the dictionary
{ 'Key1': (1, 2) }
How can I add another pair of integers to the following dictionary to the following key in order to have
{ 'Key1': (1, 2), (1, 3), (1, 4)}
Is it possible to do it in Python? if yes How can I do it?
Can I also count the number of values that correspond to a specific key?
Yes its possible but you need to use a container for your values.
For example you can use a list,also you can use dict.setdefault method for assignment if your keys will have a multiple values, this is useful of you want to add another key with multiple values :
>>> d = {}
>>> d.setdefault('Key1',[]).append((1,2))
>>> d
{'Key1': [(1, 2)]}
>>> d['Key1'].append((1, 3))
>>> d
{'Key1': [(1, 2), (1, 3)]}
>>> d.setdefault('Key2',[]).append((4,2))
>>> d
{'Key2': [(4, 2)], 'Key1': [(1, 2), (1, 3)]}
setdefault(key[, default])
If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.
That's only possible if you make the initial entry a list.
D['key'] = []
D['key'].append((1,2))
D['key'].append((3,4))
{'Key': [(1,2), (3,4)] }
You can't do it directly; in other words, a dict can't hold multiple values associated with the same key. You would need to have a dict of lists.
If the set of keys isn't known in advance, you might want to use a defaultdict, which will automatically create a list (or whatever) each time you access a key which doesn't already exist in the dictionary.
d = collections.defaultdict(list)
To add elements, you would use
d['Key1'].append((1, 2))
instead of
d['Key1'] = (1, 2)
This lets you avoid writing special code to handle the first insertion with a given key.

How to find the number value set to a specific character within a string (without counting) in python [duplicate]

This question already has answers here:
How to find all occurrences of an element in a list
(18 answers)
How to find all occurrences of an element in a list?
(2 answers)
Closed 9 years ago.
I recently got a project in which I need to find all of the indices where a specific character appeared in a string inputted by the user.
For example the user inputs the string "This is a test" and I wanted to find the indices of all the t's in the string I would get 0, 11, 14
I looked through the built in commands and couldn't find anything so it would be a real help to know a method to find this.
Use enumerate and a list comprehension:
st="This is a test"
print([i for i, c in enumerate(st) if c.lower()=='t'])
Or:
print([i for i, c in enumerate(st) if c in 'tT'])
In either case, prints:
[0, 10, 13]
Explanation
First thing that 'makes this work' is that strings are iterable in Python:
>>> st="This is a test"
>>> for c in st:
... print c
...
T
h
i
s
i
s
a
t
e
s
t
Second thing that makes this work is enumerate which adds a count of all the characters in the string as a tuple:
>>> for tup in enumerate(st):
... print tup
...
(0, 'T')
(1, 'h')
(2, 'i')
(3, 's')
(4, ' ')
(5, 'i')
(6, 's')
(7, ' ')
(8, 'a')
(9, ' ')
(10, 't')
(11, 'e')
(12, 's')
(13, 't')
Pulling those two concepts together into a list comprehension produces the result:
[i for i, c in enumerate(st) if c.lower()=='t']
^^^ Produces the tuple of index and character
^ ^ Index, Character
^^^^^^^^^^^ test the character if it is 't'
^ What is wanted - list of indices
Just a straightforward approach as an alternative to a (better) enumerate option:
[range(len(st))[i] for i in range(len(st)) if st[i].lower() == 't']

Resources