How to count the numbers in values in a dictionary - python

I'm trying to count the amount of values that contain numbers that show up in the values of dictionary entries, and then put them in a list. So for example:
some_dictionary = {'FIRST' : ['a', '1', 'b', '2'],
'SECOND' : ['c', 'd', '3', 'e'],
'THIRD' : ['4', '5', 'f', 'g6']}
some_dictionary_values = [2, 1, 3]
So far I have:
for key, value in some_dictionary.items():
for string in value:
if any(char.isdigit() for char in string):
amount_of_numbers.append(string)
but this seems like a really roundabout way of doing it. I'd like to know if I'm on the right track or if there's an easier way of going about this.
edit: I guess my question wasn't very clear. Let me give another example:
dictionary = {'ONE' : ['abc', '123', 'def']
'TWO' : ['happy', '42', 't4']
'THREE' : ['word2', 'word', 'words']}
So the key 'ONE' has the values 'abc', '123', and 'def'. Of these values, only one of them contains a number, so in the list this would show up as 1.
The key 'TWO' has two values which contain numbers, '42' and 't4'.
The key 'THREE' has one value which contains a number, 'word2'.
Therefore the final list will be:
final_list = [1, 2, 1]
I hope that made my problem clearer.

Edited Answer
amount_of_numbers = {}
for key, value in some_dictionary.items():
amount_of_numbers[key] = len ([string for string in value if all(char.isdigit() for char in string) ])
print amount_of_numbers
{'SECOND': 1, 'THIRD': 2, 'FIRST': 2}
Original Answer
Here you go:
some_dictionary = {'FIRST' : ['a', '1', 'b', '2'],
'SECOND' : ['c', 'd', '3', 'e'],
'THIRD' : ['4', '5', 'f', 'g6']}
amount_of_numbers = []
for value in some_dictionary.values():
amount_of_numbers += [string for string in value if all(char.isdigit() for char in string)]
print amount_of_numbers
['3', '4', '5', '1', '2']
Note that your current implementation is incorrect, it includes g6 also in the output, even though it is not a number

This one-liner utilizes the fact that in arithmetical expressions boolean behaves as integer
{key: sum(any(c.isdigit() for c in word) for word in value)
for key, value in some_dictionary.iteritems()}

Related

Creating a list with specific values from a list of dictionaries (keys as strings and values are list of integers)

I have a list of dictionaries with a string and a list of strings as values for their respective keys:
list_of_dictionaries = [
{'id': 'ABBA', 'num': ['10', '3', '5', '1']},
{'id': 'ABAC', 'num': ['4', '5', '6', '20']}]
Each letter in the 'id' string corresponds with the number in 'num' at matching indices. So for value 'ABBA' it would match the value in 'num' at each position in order: A = 10, B = 3, B = 5, A = 1. I would like return a list of the ids with 'num' > 5 in each dictionary while maintaining their current order.
Here is my attempt:
bad_values = ['','0','1','2','3','4','5']
final_ids =[]
for i in list_of_dictionaries:
list_of_high_num =[]
for id,num in enumerate(i.items()):
if i["num"] is not bad_values:
list_of_high_num.append(i["id"])
final_ids.append(list_of_high_num)
However, I'm just getting my original string of ids back in a list. Where am I going wrong?
Desired output something like this:
final_list = [['A'], ['A', 'C']]
considering the scenario for each dictionary item len(id) = len(num)
list_of_dictionaries = [
{'id': 'ABBA', 'num': ['10', '3', '5', '1']},
{'id': 'ABAC', 'num': ['4', '5', '6', '20']}]
limit = 5
outerlist = []
for d in list_of_dictionaries:
innerlist = []
for x in range(len(d['num'])):
if int(d['num'][x]) > limit:
innerlist.append(d['id'][x])
outerlist.append(innerlist)
print(outerlist) # [['A'], ['A', 'C']]

Code works only sometimes for removing odd or even index items

Question :​ Write a Python program to remove the characters which have odd or even index
values of a given string.
I tried to make a copy of the list by deep copy .
I ran a loop from first list and checked for even then used pop method on second list to remove that specific index from the second list .
This code works for some inputs , I think mostly for those which doesn't have any repeated characters and doesn't work for others.
Code
#!/usr/bin/python3
import copy
list1 = input("Enter a string ")
list1 = list(list1)
list2 = copy.deepcopy(list1)
for i in list1:
if list1.index(i)%2 != 0:
list2.pop(list2.index(i))
print(list2)
The outputs for some samples are :
123456789 -> ['1', '3', '5', '7', '9'], qwertyuiop -> ['q', 'e', 't', 'u', 'o'], saurav -> ['s', 'u'], 11112222333344445555 -> ['1', '1', '1', '1', '2', '2', '2', '2', '3', '3', '3', '3', '4', '4', '4', '4', '5', '5', '5', '5']
Read the documentation for index. It returns the index of the first occurrence of the given value. A simple print inside the loop will show you what's going on, in appropriate detail. This is a basic debugging skill you need to learn for programming in any language.
import copy
list1 = input("Enter a string ")
list1 = list(list1)
list2 = copy.deepcopy(list1)
for i in list1:
if list1.index(i)%2 != 0:
print(i, list1.index(i), list2.index(i))
list2.pop(list2.index(i))
print(list2)
print(list2)
output:
Enter a string google
o 1 1
['g', 'o', 'g', 'l', 'e']
o 1 1
['g', 'g', 'l', 'e']
e 5 3
['g', 'g', 'l']
['g', 'g', 'l']
... and that's your trouble. Fix your logic. You already know the needed index to save or remove. There is no need to extract the character, and then search for it again. You already know where it is.
Even better, simply slice the original string for the characters you want:
print(list1[::2])
Your problem is the list.index function. The documentation states that it "returns zero-based index in the list of the first item whose value is equal to x." Because you are calling it on list1 - and that is not modified - the result will always be list1.index('a') == 1 for example.
The correct solution would be to use enumerate. A further problem exists here - because you are indexing from an array that you have not modified, you indexes will be off after the first list.pop operation. Every item after the one removed will have been shifted by 1. To correct this, you could instead try building a list instead of emptying one:
#!/usr/bin/python3
list1 = input("Enter a string ")
list2 = []
for i, item in enumerate(list1):
if i % 2 == 0:
list2.append(item)
print(list2)
You don't need to iterate at all. Just reference the string elements directly.
st="123456789"
print('Odd: ', list(st[::2]))
print('Even: ', list(st[1::2]))
Output:
Odd: ['1', '3', '5', '7', '9']
Even: ['2', '4', '6', '8']
The method list.index(i) returns index in the list of the first item whose value is equal to i.
For example, "saurav".index('a') returns 1. when you call list2.pop(list2.index(i)) and you want to pop an a, it doesn't work well.
I think it can be simple using range as build-in function.
list1 = list(input("Enter a string "))
list2 = list()
for i in range(len(list1)):
if i % 2 == 0:
list2.append(list1[i])
print(list2)
It works with same way by following:
list1 = list(input("Enter a string "))
list2 = list()
for i in range(0, len(list1), 2):
list2.append(list1[i])
print(list2)
Also, you can use Extended Slices in Python 2.3 or above.
list1 = list(input("Enter a string "))
list2 = list1[::2]
print(list2)

How to split an array of arrays?

I have this array that contains some other arrays in Python, but I need only the first elements of each mini array inside the main array. Is there some method to do that?
Example:
array = [['a','1'], ['b','2'], ['c','3'], ['d','4'], ['e','5']]
I need the letters in one row:
'a'
'b'
'c'
'd'
'e'
And the numbers in another:
'1'
'2'
'3'
'4'
'5'
can You help me with this?
You can use zip to separate letters from numbers and map to convert the tuples returned by zip to lists:
array = [['a','1'], ['b','2'], ['c','3'], ['d','4'], ['e','5']]
letters, numbers = map(list, zip(*array))
print(letters)
print(numbers)
Output:
['a', 'b', 'c', 'd', 'e']
['1', '2', '3', '4', '5']
You can use comprehension. a[0] means first item in a list
[a[0] for a in array]
Result:
['a', 'b', 'c', 'd', 'e']
You can use
letters,numbers = tuple(zip(*array))

Value look-up for Dictionary inside a dictionary in Python

I have a Python dictionary in this format :
mongo = {
1: {'syno': ['a','b','c'], 'can': ['2','3','4']},
2 :{'syno': ['x','y','z'], 'can': ['6','7','8']},
}
and I have a list called syno_iter:
syno_iter = ['a','b','c','d','e']
Using a single value in syno_iter, let's suppose a. I want to get the values in the can in the mongo{} as in if the value a is available in the value of the value syno, we can return can.
We don't have any way of knowing the keys of mongo dict. Also as dictionaries are not iterable we can't use range thing.
To reiterate:
I want to do something like this-
for i in syno_iter:
if i in (mongo.values('syno')):
print mongo.values('can'(values()))
input - 'a'
output - ['2','3','4']
You can perform a lookup like that with:
Code:
def get_syno_values(data, lookup):
for row in data.values():
if lookup in row['syno']:
return row['can']
Test Code:
mongo = {
1: {'syno': ['a', 'b', 'c'], 'can': ['2', '3', '4']},
2: {'syno': ['x', 'y', 'z'], 'can': ['6', '7', '8']}
}
syno_iter = ['a', 'b', 'c', 'd', 'e']
print(get_syno_values(mongo, 'a'))
print(get_syno_values(mongo, 'y'))
Results:
['2', '3', '4']
['6', '7', '8']

Python Dictionary - Find min key where value is equal to

I have a dictionary I would like to find the minimum key where value[1] is equal to a a specified string.
somedict = {'1': ['110', 'A'], '3': ['1', 'A'], '2': ['3', 'B'], '4': ['1', 'B']}
mindict = min(somedict.iteritems(), key=itemgetter(0) )
This gives me ('1', ['110', 'A'])
I would like to further filter this by finding the min key where value is 'B'
to give me the result ('2', ['3', 'B'])
How would go about this?
Use a generator expression filtering your items first:
min((i for i in somedict.iteritems() if i[1][-1] == 'B'), key=itemgetter(0))
The generator expression produces elements from somedict.iteritems() where the last entry in the value is equal to 'B'.
Note that there is a risk here that no items match your filter! If that could be the case, make sure you catch the ValueError thrown by min() when passed an empty sequence. If you are using Python 3.4 or newer, you can specify a default to be returned for that case:
min((i for i in somedict.iteritems() if i[1][-1] == 'B'),
key=itemgetter(0), default=())
which would return an empty tuple if no items have a last entry 'B' in their value.
Demo:
>>> from operator import itemgetter
>>> somedict = {'1': ['110', 'A'], '3': ['1', 'A'], '2': ['3', 'B'], '4': ['1', 'B']}
>>> min((i for i in somedict.iteritems() if i[1][-1] == 'B'), key=itemgetter(0))
('2', ['3', 'B'])

Categories

Resources