Split keys (12-13-14) of a dict and find lowest number - python

What loop can I build to split the following two keys from dictionary "x", and assign the lowest value to a string?
x.keys()
['12-13-14', '1-2-3']
The output should be the following string:
['12', '1']
I know I probably need .split("-"), but I don't know how to write the loop to do this.

No loop needed; just use a list comprehension.
>>> keys = ['12-13-14', '1-2-3']
>>> [str(min(int(x) for x in key.split('-'))) for key in keys]
['12', '1']
What this does: for each key in keys, it splits the key by - using split('-'), just as you thought, and converts those to int (because 2 < 12, but '2' > '12'), finds the min of those, and convert back to str.
Or even shorter (and much more concise), as suggested by #poke:
>>> [min(key.split('-'), key=int) for key in keys]
This does not convert to int and back to str, but instead uses int as the key function by which to determine the minimum.

Related

How can I access the key of dictionary ,with matching values of it with another external list?

I want to access the key of dictionary by checking equality of its value with an element of another list.
def split(word):
return [char for char in word]
word = '26kk15'
d={'3':['1','2'],'4':['5','6'],'s':['k','l']}
keys=list(d.keys())
l=len(d)
c=0
nl=split(word)
for k in range(0,len(nl)):
for iu in d.values():
for j in iu:
if(j==nl[k]):
print(keys[c])
c+=1
I am getting list index out of range error.
And if I remove the outer for loop it will give me output as 3 4 s,while I want \n3\n4\ns\ns\n3\n4.
c is going out of range because you don't reset it to 0 each time you iterate over d.values().
But there's no need for all those extra lists. Use .items() to iterate over both the keys and values of the dictionary, so you can print the key when you find a matching value.
You should use the in operator to test whether something is in the list, without another nested loop.
for letter in word:
for key, chars in d.items():
if letter in chars:
print(key)
break
in Python it's easier to iterate through a collection directly rather than getting it's length, iterate through numeric indices and then lookup up the item back again via index. You can even iterate through a string directly without converting it to a list.
d = {'3': ['1', '2'], '4': ['5', '6'], 's': ['k', 'l']}
word = '26kk15'
for needle in word:
for key, haystack in d.items():
# check if the character is in the dict item
if needle in haystack:
# if it is, print it and `break` the search loop for given character
print(key)
break
Here is the code to obtain what you need using python regex:
import re
word = '26kk15'
d={'3':['1','2'],'4':['5','6'],'s':['k','l'], 'b': ['8', '9']}
for key, values in d.items():
# Check if elements in 'values' are part of 'word'
if re.search(r"|".join(values), word):
print (key)
Output:
3
4
s

sorting list of tuple based on engineering unit

I am trying to sort list into following way.
data = [('18.3G', 'pgaur'), ('29.6G', 'adsoni'), ('5.51G', 'keyur'), ('10.8G', 'adityac')]
sorted(data, key= lambda x:x[0])
but it is not sorting data.
To sort numbers in the way that makes sense to humans, you have to make sure that they are presented as numbers and not as text:
e.g., '5' is a string representing a number, not a number so
example_list = ['5', '10'] if sorted would yield `['10', '5']
because what's compared is '5' against '1'; one character at a time.
To get the result you probably want, you have to do the following:
data = [('18.3G', 'pgaur'), ('29.6G', 'adsoni'), ('5.51G', 'keyur'), ('10.8G', 'adityac')]
sorted_list = sorted(data, key=lambda x: float(x[0][:-1]))
print(sorted_list)
# prints [('5.51G', 'keyur'), ('10.8G', 'adityac'), ('18.3G', 'pgaur'), ('29.6G', 'adsoni')]
Notice the slicing on the x[0]. It takes all characters in x[0] apart from the last one ('G') since that would mess up the sorting of the number. Then the sliced x[0] is converted to float with float() and used for the sorting. Finally the results are saved in a new list.
sorted(data, key= lambda x:float(x[0][:][:-1]))
Will give you what you want.
This is sorting by the first element of the tuple x[0]
[:] copies the rest of the tuple, [:-1] up to the last digit (excludes G)
Ideally you need a key function that returns a numeric value. Let's suppose that you can use k, m and g as multipliers. This code does no error checking which is, as usual, left as an exercise for the reader.
def sortkey(pair):
num = pair[0][:-1]
mult = pair[0][-1].lower()
num = float(num)
mult = {'k': 1000, 'm': 1000000, 'g': 1000000000}[mult]
return num*mult

why sort in python is not working?

code:
list=['1','85863','432','93','549834']
list.sort()
print (list)
Actual output:
>>>
['1', '432', '549834', '85863', '93']
#why sort is not working
Expected output:
['1','93','432','83863','549834']
I have tried other sort operations also but they are displaying same output.
when i tried to read list from keyboard input they are reading only strings but not int please help me why?
when i tried to read list from keyboard input they are reading only strings but not int please help me why
if x is a string, just use int(x) to convert to int
You're sorting strings (text), not by numerical values like integers
For your expected output you have to convert to ints first
my_list= ['1','85863','432','93','549834']
my_list = [int(x) for x in my_list]
Now you can sort numerically, and get a list of ints
my_list.sort()
N.B. avoid using list as variable name, it is a Python built-in
I presume you want to sort by the sum to match your expected output:
l = ['1','85863','432','93','549834']
l.sort(key=lambda x: sum(map(int,x)))
print(l)
['1', '432', '93', '83863', '549834']
You need to first convert the strings to int.
list = [int(ele) for ele in list]
list.sort()
print list
Without int:
lst = ['1','85863','432','93','549834']
lst.sort()
lst.sort(key=len)
print(lst)
This give:
['1', '93', '432', '85863', '549834']
And if you want integers…
my_int = int(input())
I simply missed the logic of converting a string into int.By default python input will be taken as a string. so,we can use any method mentioned in the answers to convert in to string and then sort() method works succesufully over int

Python build one dictionary from a list of keys, and a list of lists of values

So I have a list of keys:
keys = ['id','name', 'date', 'size', 'actions']
and I also have a list of lists of vales:
values=
[
['1','John','23-04-2015','0','action1'],
['2','Jane','23-04-2015','1','action2']
]
How can I build a dictionary with those keys matched to the values?
The output should be:
{
'id':['1','2'],
'name':['John','Jane'],
'date':['23-04-2015','23-04-2015'],
'size':['0','1'],
'actions':['action1','action2']
}
EDIT:
I tried to use zip() and dict(), but that would only work if the list of values had 1 list, i.e. values = [['1','John','23-04-2015','0','action1']]
for list in values:
dic = dict(zip(keys,list))
I also thought about initialising a dic with the keys, then building the list of values on my own, but I felt that there had to be an easier way to do it.
dic = dict.fromkeys(keys)
for list in values:
ids = list[0]
names = list[1]
dates = list[2]
sizes = list[3]
actions = list[4]
and then finally
dic['id'] = ids
dic['name'] = names
dic['date'] = dates
dic['size'] = sizes
dic['action'] = actions
This seemed really silly and I was wondering what a better way of doing it would be.
>>> keys = ['id','name', 'date', 'size', 'actions']
>>> values = [['1','John','23-04-2015','0','action1'], ['2','Jane','23-04-2015','1','action2']]
>>> c = {x:list(y) for x,y in zip(keys, zip(*values))}
>>> c
{'id': ['1', '2'], 'size': ['0', '1'], 'actions': ['action1', 'action2'], 'date': ['23-04-2015', '23-04-2015'], 'name': ['John', 'Jane']}
>>> print(*(': '.join([item, ', '.join(c.get(item))]) for item in sorted(c, key=lambda x: keys.index(x))), sep='\n')
id: 1, 2
name: John, Jane
date: 23-04-2015, 23-04-2015
size: 0, 1
actions: action1, action2
This uses several tools:
c is created with a dictionary comprehension. Comprehensions are a different way of expressing an iterable like a dictionary or a list. Instead of initializing an empty iterable and then using a loop to add elements to it, a comprehension moves these syntactical structures around.
result = [2*num for num in range(10) if num%2]
is equivalent to
result = []
for num in range(10):
if num%2: # shorthand for "if num%2 results in non-zero", or "if num is not divisible by 2"
result.append(2*num)
and we get [2, 6, 10, 14, 18].
zip() creates a generator of tuples, where each element of each tuple is the corresponding element of one of the arguments you passed to zip().
>>> list(zip(['a','b'], ['c','d']))
[('a', 'c'), ('b', 'd')]
zip() takes multiple arguments - if you pass it one large list containing smaller sublists, the result is different:
>>> list(zip([['a','b'], ['c','d']]))
[(['a', 'b'],), (['c', 'd'],)]
and generally not what we want. However, our values list is just such a list: a large list containing sublists. We want to zip() those sublists. This is a great time to use the * operator.
The * operator represents an "unpacked" iterable.
>>> print(*[1,2,3])
1 2 3
>>> print(1, 2, 3)
1 2 3
It is also used in function definitions:
>>> def func(*args):
... return args
...
>>> func('a', 'b', [])
('a', 'b', [])
So, to create the dictionary, we zip() the lists of values together, then zip() that with the keys. Then we iterate through each of those tuples and create a dictionary out of them, with each tuple's first item being the key and the second item being the value (cast as a list instead of a tuple).
To print this, we could make a large looping structure, or we can make generators (quicker to assemble and process than full data structures like a list) and iterate through them, making heavy use of * to unpack things. Remember, in Python 3, print can accept multiple arguments, as seen above.
We will first sort the dictionary, using each element's position in keys as the key. If we use something like key=len, that sends each element to the len() function and uses the returned length as the key. We use lambda to define an inline, unnamed function, that takes an argument x and returns x's index in the list of keys. Note that the dictionary isn't actually sorted; we're just setting it up so we can iterate through it according to a sort order.
Then we can go through this sorted dictionary and assemble its elements into printable strings. At the top level, we join() a key with its value separated by ': '. Each value has its elements join()ed with ', '. Note that if the elements weren't strings, we would have to turn them into strings for join() to work.
>>> list(map(str, [1,2,3]))
['1', '2', '3']
>>> print(*map(str, [1,2,3]))
1 2 3
The generator that yields each of these join()ed lines is then unpacked with the * operator, and each element is sent as an argument to print(), specifying a separator of '\n' (new line) instead of the default ' ' (space).
It's perfectly fine to use loops instead of comprehensions and *, and then rearrange them into such structures after your logic is functional, if you want. It's not particularly necessary most of the time. Comprehensions sometimes execute slightly faster than equivalent loops, and with practice you may come to prefer the syntax of comprehensions. Do learn the * operator, though - it's an enormously versatile tool for defining functions. Also look into ** (often referred to with "double star" or "kwargs"), which unpacks dictionaries into keyword arguments and can also be used to define functions.

How to print the longest dictionary value?

I have a dictionary whose values are all lists of strings and I want to print the longest value(in this case, the list with the most strings). I created this for loop:
count=0
for values in d.values():
if len(values)>count:
count=len(values)
print(values)
However, this prints all of the values ever associated with 'count'. I only want the largest one (which is the last line). This is an example of what the for loop prints:
['gul', 'lug']
['tawsed', 'wadset', 'wasted']
['lameness', 'maleness', 'maneless', 'nameless', 'salesmen']
['pores', 'poser', 'prose', 'repos', 'ropes', 'spore']
['arrest', 'rarest', 'raster', 'raters', 'starer', 'tarres', 'terras']
['carets', 'cartes', 'caster', 'caters', 'crates', 'reacts', 'recast', 'traces']
['estrin', 'inerts', 'insert', 'inters', 'niters', 'nitres', 'sinter', 'triens', 'trines']
['least', 'setal', 'slate', 'stale', 'steal', 'stela', 'taels', 'tales', 'teals', 'tesla']
['apers', 'apres', 'asper', 'pares', 'parse', 'pears', 'prase', 'presa', 'rapes', 'reaps', 'spare', 'spear']
How can I get it to print only that last(longest) line?
max(d.values(), key=len)
This prints out the longest list of words from your dict values. I used the max() function, which takes a key parameter that is assigned to the function len(in this case). Basically, the criteria for which value is the 'max' value is now decided by it's len.
Inspired by Dilbert there is a chance for simplification, no need to use lambda to define function for comparing values, we may take advantage of the fact, that len returns length of each item and this is perfect key for deciding who comes first and who is last:
print sorted(d.values(), key=len)[-1]
count = 0
for values in d.values():
if len(values) > count:
values_with_largest_count_first_hit = values
print(values_with_largest_count_first_hit)
print sorted(d.values(), cmp = lambda x, y: cmp(len(x), len(y)))[-1]

Categories