This question already has answers here:
How to return dictionary keys as a list in Python?
(13 answers)
Closed 4 years ago.
I have the following data:
[{'id': ['132605', '132750', '132772', '132773', '133065', '133150', '133185', '133188', '133271', '133298']},
{'number': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']},
{'id': ['1', '1', '1', '1', '1', '1', '1', '1', '1', '1']}]
What would be the best way to get a list of the keys (as if it was a dict and not an array)? Currently I'm doing:
>>> [list(i.keys())[0] for i in e.original_column_data]
['id', 'number', 'id']
But that feels a bit hackish
What is hacky about it? It's a bit inelegant. You just need to do the following:
>>> keys = []
>>> data = [{'id': ['132605', '132750', '132772', '132773', '133065', '133150', '133185', '133188', '133271', '133298']},
... {'number': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']},
... {'id': ['1', '1', '1', '1', '1', '1', '1', '1', '1', '1']}]
>>> for d in data:
... keys.extend(d)
...
>>> keys
['id', 'number', 'id']
Or if you prefer one-liners:
>>> [k for d in data for k in d]
['id', 'number', 'id']
first way
iteration on a dictionary gives you its keys, so a simple
>>> [key for key in dict]
gives you a list of keys and you can get what you want with
>>> [key for dict in dict_list for key in dict]
second way (only python 2)
use .key() (used in your code)
but there is no need to use list() (edit: for python 2)
here's what it will look like:
>>> [dict.keys()[0] for dict in dict_list]
in your code, dictionaries have only one key so these two have the same result.
but I prefer the first one since it gives all keys of all the dictionaries
This is simpler and does the same thing:
[k for d in e.original_column_data for k in d]
=> ['id', 'number', 'id']
Related
I need to delete the elements that are duplicated in a dictionary like this:
{
1: ['1', '2', '3'],
2: ['4', '3', '6', '7'],
3: ['8', '1', '9']
}
as to make the final result like this
{
1: ['1', '2', '3'],
2: ['4', '6', '7'],
3: ['8', '9']
}
Please help me how to do that, I have no idea
Assuming d the input, you can use a set to keep track of the seen values. Here using a dictionary comprehension and "cheating" a bit to add the values:
seen = set()
out = {k: [x for x in v
if x not in seen and not seen.add(x)]
for k,v in d.items()}
Output:
{1: ['1', '2', '3'],
2: ['4', '6', '7'],
3: ['8', '9']}
Same with a classical loop:
out = {}
seen = set()
for k,v in d.items():
l = []
for x in v:
if x not in seen:
seen.add(x)
l.append(x)
out[k] = l
Rehashing the same old seen-set solution is boring :-P. Let's have some fun with Counters:
from collections import Counter
d = {
1: ['1', '2', '3'],
2: ['4', '3', '6', '7'],
3: ['8', '1', '9']
}
seen = Counter()
for a in d.values():
uniq = Counter(dict.fromkeys(a, 1))
a[:] = uniq - seen
seen |= uniq
print(d)
Each list is first deduplicated on its own by using a dict. Then turned into a Counter so we can conveniently subtract the previously seen values. Write the new ones into the list and add them to the seen ones.
Try it online!
You could do the same with set union and difference operators. As sets are unordered the final list would need to be sorted. Again assuming d is the original dictionary.
s = set()
for k in d:
z = d[k]
d[k]= sorted(list(set(z).difference(s)))
s |= set(z)
This question already has answers here:
Slicing a dictionary by keys that start with a certain string
(3 answers)
Closed 2 years ago.
I have a dictionary like this:
'id': 6, 'user_id': 1, 'approved': 0, 'is_ok': 0, 'solution': '2', 'category': '2', 'language': '2', 'hint_1': '1', 'hint_2': '2', 'hint_3': '3', 'hint_4': '4', 'hint_5': '5', 'hint_6': '6', 'hint_7': '7', 'hint_8': '8', 'hint_9': '9', 'hint_10': '2', 'hint_11': '2', 'hint_12': '2', 'hint_13': '2', 'hint_14': '2', 'hint_15': '2', 'hint_16': '2', 'hint_17': '2', 'hint_18': '2', 'hint_19': '2', 'hint_20': '2'
Is there a way to get a list of all values, where the key starts with hint_?, ? being placeholder?
Thanks.
I think it could be done via a function that compares strings, but there might be a better solution!?
Handy one-liner:
[item for key, item in dictionary.items() if key.startswith('hint_')]
This question already has answers here:
How to sort python list of strings of numbers
(4 answers)
Closed 2 years ago.
I tried to sort a list of string that are actually integers but i do not get the right sort value. How do i sort it in a way that it is sorted according to the integer value of string ?
a = ['10', '1', '3', '2', '5', '4']
print(sorted(a))
Output:
['1', '10', '2', '3', '4', '5']
Output wanted:
['1', '2', '3', '4', '5', '10']
We have to use the lambda as a key and make each string to int before the sorted function happens.
sorted(a,key=lambda i: int(i))
Output :
['1', '2', '3', '4', '5', '10']
More shorter way -> sorted(a,key=int). Thanks to #Mark for commenting.
So one of the ways to approach this problem is converting the list to a list integers by iterating through each element and converting them to integers and later sort it and again converting it to a list of strings again.
You could convert the strings to integers, sort them, and then convert back to strings. Example using list comprehensions:
sorted_a = [str(x) for x in sorted(int(y) for y in a)]
More verbose version:
int_a = [int(x) for x in a] # Convert all elements of a to ints
sorted_int_a = sorted(int_a) # Sort the int list
sorted_str_a = [str(x) for x in sorted_int_a] # Convert all elements of int list to str
print(sorted_str_a)
Note: #tedd's solution to this problem is the preferred solution to this problem, I would definitely recommend that over this.
Whenever you have a list of elements and you want to sort using some property of the elements, use key argument (see the docs).
Here's what it looks like:
>>> a = ['10', '1', '3', '2', '5', '4']
>>> print(sorted(a))
['1', '10', '2', '3', '4', '5']
>>> print(sorted(a, key=lambda el: int(el)))
['1', '2', '3', '4', '5', '10']
I'm currently dealing with the below list:
[['John', '1', '2', '3'], ['Doe', '1', '2', '3']]
I'm incredibly new to python, I'm wanting to order this list in numerical order (high - low) but maintain the string at the beginning of the list. Like this:-
[['John', '3', '2', '1'], ['Doe', '3', '2', '1']]
There will always be one name & integers there after.
I collect this list from a csv file like so:-
import csv
with open('myCSV.csv', 'r') as f:
reader = csv.reader(f)
your_list = list(reader)
print(sorted(your_list))
Any help is much appreciated. Thanks in advance..
Iterate over the list and sort only the slice of each sublist without the first item. To sort strings as numbers pass key=int to sorted. Use reverse=True since you need a reversed order:
>>> l = [['John', '1', '2', '3'], ['Doe', '1', '2', '3']]
>>>
>>> [[sublist[0]] + sorted(sublist[1:], key=int, reverse=True) for sublist in l]
[['John', '3', '2', '1'], ['Doe', '3', '2', '1']]
For example I want to remove the extra 1s and 2s in this tuple ( '1',
'1',
'1',
'1',
'1',
'1',
'1',
'2',
'2',
'2') to return ('1', '2')
How can I do this?
You can't modify tuple in place, So definitely you have to get new tuple. You can use set to remove duplicate elements.
>>> tp = ( '1', '1', '1', '1', '1', '1', '1', '2', '2', '2')
>>> tp = tuple(set(tp))
>>> tp
('1', '2')
As Alok correctly mentions, you have to create a new tuple. As Alok demonstrates, you can of course assign it to the variable that previously held the original tuple.
If you don't care about order, use set as Alok suggests. If you however want to preserve the order (of first occurrence of each unique value), you can use a very similar trick with an OrderedDict:
from collections import OrderedDict
# Different example to demonstrate preserved order
tp = ('2', '2', '2', '1', '1', '1', '1', '1', '1', '1')
tp = tuple(OrderedDict.fromkeys(tp).keys())
# Now, tp == ('2', '1')
They are correct, tuples in python are immutable therefore you cannot update the current tuple. This function loops through data creating a list of indexes that do not currently exist! It then returns a tuple of the list! Good luck!
data = ( '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '3', '4','4')
def removeDoubles(data):
out = []
for i in data:
if i in out:
continue
out.append(i)
del data
return tuple(out)
print removeDoubles(data)
You can do this using a set:
a = ( '1', '1', '1', '1', '1', '1', '1', '2', '2', '2')
b = tuple(set(a))
If the order is important you could sort b.