Loop to gradually to remove elements to dictionary in Python - python

I have a dictionary that for example looks like this:
new_dict = {
0: ['1'],
1: ['1', '2'],
2: ['1', '2', '3'],
3: ['1', '2', '3', '4'],
4: ['1', '2', '3', '4', '5'],
5: ['1', '2', '3', '4', '5', '6']
}
the values are just gradually appended, meaning that the next value contains the elements of the previous value + its own value.
and my question is, how can I, starting from key=3 included, remove gradually all the starting values?
so for example, for key=3, after the code the new key=3 should look like this:
3: ['2', '3', '4'] #Should remove the value of key=0
then for key=4, the new key=4 should look like this:
4: ['3', '4', '5'] #Should remove the value of key=1
And so on til the end of new_dict.

Here is a relatively compact solution:
new_dict = {0: ['1'], 1: ['1', '2'], 2: ['1', '2', '3'], 3: ['1', '2', '3', '4'], 4: ['1', '2', '3', '4', '5'], 5: ['1', '2', '3', '4', '5', '6']}
up_dict={i:[item for item in new_dict[i] if item not in new_dict[i-3]] if i>2 else new_dict[i] for i in new_dict}
print(up_dict)
Output:
{0: ['1'], 1: ['1', '2'], 2: ['1', '2', '3'], 3: ['2', '3', '4'], 4: ['3', '4', '5'], 5: ['4', '5', '6']}

You can loop through the items and reassign the list to the last three elements:
In [1]: new_dict = {0: ['1'], 1: ['1', '2'], 2: ['1', '2', '3'], 3: ['1', '2', '3', '4'], 4: ['1', '2', '3', '4', '5'], 5: ['1', '2', '3', '4', '5', '6']}
In [2]: for k, v in new_dict.items():
...: if len(v) > 3:
...: new_dict[k] = v[-3:]
...:
In [3]: new_dict
Out[3]:
{0: ['1'],
1: ['1', '2'],
2: ['1', '2', '3'],
3: ['2', '3', '4'],
4: ['3', '4', '5'],
5: ['4', '5', '6']}
As a dict comprehension:
out_dict = {k: v[-3:] if len(v) > 3 else v for k, v in new_dict.items()}

You can use dictionary comprehension, and take the key value pair as it is if key<3 else take only the items that are not in the values for key at 0,1,2, and so on.
{k:new_dict[k] if idx<0 else [i
for i in new_dict[k] if i not in new_dict[idx]]
for idx,k in enumerate(new_dict, -3)}
OUTPUT:
{0: ['1'],
1: ['1', '2'],
2: ['1', '2', '3'],
3: ['2', '3', '4'],
4: ['3', '4', '5'],
5: ['4', '5', '6']}

This should do the job and be quite efficient as well, if that's important to you:
new_dict = {0: ['1'], 1: ['1', '2'], 2: ['1', '2', '3'], 3: ['1', '2', '3', '4'], 4: ['1', '2', '3', '4', '5'], 5: ['1', '2', '3', '4', '5', '6']}
print({key:(value,value[key-2:])[key//3] for key,value in new_dict.items()})
>>> {0: ['1'], 1: ['1', '2'], 2: ['1', '2', '3'], 3: ['2', '3', '4'], 4: ['3', '4', '5'], 5: ['4', '5', '6']}

Shorter comprehension-based solution:
new_dict = {0: ['1'], 1: ['1', '2'], 2: ['1', '2', '3'], 3: ['1', '2', '3', '4'], 4: ['1', '2', '3', '4', '5'], 5: ['1', '2', '3', '4', '5', '6']}
c = 0
r = {a:b if a < 3 else b[(c:=c+1):] for a, b in new_dict.items()}
Output:
{0: ['1'], 1: ['1', '2'], 2: ['1', '2', '3'], 3: ['2', '3', '4'], 4: ['3', '4', '5'], 5: ['4', '5', '6']}

Related

Check if number exists in sublist and return indexes of sublist in python

Input:
[['1', '2'], ['2', '3'], ['4', '5'], ['6', '7'], ['7', '8'], ['2', '6'], ['9', '10'], ['10', '2'], ['3', '5']]
Output (for 2):
[0, 1, 5, 7] # 2 exists in these sublists which has 0, 1, 5, 7 indexes in main list
You can achieve this cleanly with a list comprehension.
nested_list = [['1', '2'], ['2', '3'], ['4', '5'], ['6', '7'], ['7', '8'], ['2', '6'], ['9', '10'], ['10', '2'], ['3', '5']]
indices = [
index
for index, list_ in enumerate(nested_list)
if '2' in list_
]
print(indices)
Output
[0, 1, 5, 7]
you can trying this:
def my_check(l,k):
res=[]
for i in l:
if k in i:
res.append(l.index(i))
return res
l=[['1', '2'], ['2', '3'], ['4', '5'], ['6', '7'], ['7', '8'], ['2', '6'], ['9', '10'], ['10', '2'], ['3', '5']]
print(my_check(l,'2'))
output:
[0, 1, 5, 7]

Python - Remove nested lists in dictionary

I have a dict named results.
the dict is structured in this format:
{'a': [['1', '2', '4'],['1', '2', '2'],['1', '2', '2']], 'b': [['2', '2', '4'],['2', '2', '2'],['1', '2', '4']], 'c': [['1', '2', '4'],['1', '2', '2'],['1', '2', '2']]}
I wish to remove the duplicate nested lists for each key, therefore leaving the dict with:
{'a': [['1', '2', '4'],['1', '2', '2']], 'b': [['2', '2', '4'],['2', '2', '2'],['1', '2', '4']], 'c': [['1', '2', '4'],['1', '2', '2']]}
I have tried:
newdict = {}
for k, v in results.items():
for i in v:
if i not in i:
newdict[k] = i
any help? thanks in advance!
Your code is wrong beyond repair (sorry), mostly because of those 2 lines:
if i not in i: # makes no sense testing if something is inside itself
newdict[k] = i # overwrites the key with one list
You'd have to count each list, and only keep one occurrence of each.
If order doesn't matter you could do that with a nested dict/set/list comprehension.
results = {'a': [['1', '2', '4'],['1', '2', '2'],['1', '2', '2']], 'b': [['2', '2', '4'],['2', '2', '2'],['1', '2', '4']], 'c': [['1', '2', '4'],['1', '2', '2'],['1', '2', '2']]}
newdict = {k:[list(y) for y in {tuple(x) for x in v}] for k,v in results.items()}
print(newdict)
result:
{'a': [['1', '2', '2'], ['1', '2', '4']], 'b': [['2', '2', '4'], ['1', '2', '4'], ['2', '2', '2']], 'c': [['1', '2', '2'], ['1', '2', '4']]}
using a set allows to keep unicity, but you cannot put a list in a set, so the expression converts to tuple first (which is hashable), and converts back to list once the processing is done.
In case if order is important, you can use something like this:
results = {'a': [['1', '2', '4'],['1', '2', '2'],['1', '2', '2']],
'b': [['2', '2', '4'],['2', '2', '2'],['1', '2', '4']],
'c': [['1', '2', '4'],['1', '2', '2'],['1', '2', '2']]}
print({k: [y for x, y in enumerate(v) \
if y not in v[:x]] for k, v in results.items()})
Output:
{'a': [['1', '2', '4'], ['1', '2', '2']],
'b': [['2', '2', '4'], ['2', '2', '2'], ['1', '2', '4']],
'c': [['1', '2', '4'], ['1', '2', '2']]}
To skip first sub-list and require checking only in the remaining, you could do:
print({k: [y for x, y in enumerate(v) \
if y not in v[1:x]] for k, v in results.items()})

How to find all possible combinations from nested list containing list and strings?

I am trying to get all possible pattern from list like:
input_x = ['1', ['2', '2x'], '3', '4', ['5', '5x']]
As we see, it has 2 nested list ['2', '2x'] and ['5', '5x'] here.
That means all possible pattern is 4 (2 case x 2 case), the expect output is:
output1 = ['1','2' , '3', '4', '5']
output2 = ['1','2x', '3', '4', '5']
output3 = ['1','2' , '3', '4', '5x']
output4 = ['1','2x', '3', '4', '5x']
I tried to search how to, but I can not find any examples (because of I have no idea about "keyword" to search)
I think python has inner libraries/methods to handle it.
One way to achieve this is via using itertools.product. But for using that, you need to firstly wrap the single elements within your list to another list.
For example, firstly we need to convert your list:
['1', ['2', '2x'], '3', '4', ['5', '5x']]
to:
[['1'], ['2', '2x'], ['3'], ['4'], ['5', '5x']]
This can be done via below list comprehension as:
formatted_list = [(l if isinstance(l, list) else [l]) for l in my_list]
# Here `formatted_list` is containing the elements in your desired format, i.e.:
# [['1'], ['2', '2x'], ['3'], ['4'], ['5', '5x']]
Now call itertools.product on the unpacked version of the above list:
>>> from itertools import product
# v `*` is used to unpack the `formatted_list` list
>>> list(product(*formatted_list))
[('1', '2', '3', '4', '5'), ('1', '2', '3', '4', '5x'), ('1', '2x', '3', '4', '5'), ('1', '2x', '3', '4', '5x')]
If you don't want to convert your list to all sub list then
You can try something like this :
input_x = ['1', ['2', '2x'], '3', '4', ['5', '5x'],['6','6x']]
import itertools
non_li=[]
li=[]
for i in input_x:
if isinstance(i,list):
li.append(i)
else:
non_li.append(i)
for i in itertools.product(*li):
sub=non_li[:]
sub.extend(i)
print(sorted(sub))
output:
['1', '2', '3', '4', '5', '6']
['1', '2', '3', '4', '5', '6x']
['1', '2', '3', '4', '5x', '6']
['1', '2', '3', '4', '5x', '6x']
['1', '2x', '3', '4', '5', '6']
['1', '2x', '3', '4', '5', '6x']
['1', '2x', '3', '4', '5x', '6']
['1', '2x', '3', '4', '5x', '6x']

Python - TypeError: unorderable types: str() < int()

I get this error when I try to run my code. Please help, and explain what it's trying to say!
This program is meant to find a persons ballot paper vote preferences (1st, 2nd, 3rd etc) for each candidate, and remove their first preference. That first preference is replaced by 99999, to make it easier for me.
Error:
ERROR CODE: minIndex = int(vote.index(min(vote)))
TypeError: unorderable types: str() < int()
Code:
def countVotes(voteList):
candidatePreferences = []
for vote in voteList:
minIndex = int(vote.index(min(vote)))
candidatePreferences.append(minIndex)
vote[minIndex] = 99999
return candidatePreferences
Value of vList (after calling countVotes function first time):
[[99999, '3', '4', '5', '2'], ['4', '2', '5', '3', 99999], [99999, '3', '2', '5', '4'], [99999, '2', '4', '3', '5'], [99999, '3', '4', '5', '2'], ['2', 99999, '3', '5', '4'], [99999, '3', '4', '5', '2'], ['3', '5', '2', '4', 99999], [99999, '4', '5', '2', '3'], ['5', 99999, '4', '3', '2'], ['3', '2', '5', '4', 99999], ['3', 99999, '2', '5', '4'], ['2', '5', 99999, '4', '3'], ['3', '2', 99999, '4', '5'], ['4', '5', '3', 99999, '2'], [99999, '5', '4', '3', '2'], [99999, '5', '3', '4', '2'], ['2', 99999, '4', '3', '5'], ['4', 99999, '2', '5', '3']]
Calling the function (second time):
cp = countVotes(vList)
minIndex = int(vote.index(min(vote)))
TypeError: unorderable types: str() < int()
Python cannot order str values and int values together.
In your example 99999 is an int value while all the other values are str values.
I think is this line minIndex = int(vote.index(min(vote)))
You are trying to find min on a string list. so what you can
def countVotes(voteList):
candidatePreferences = []
for vote in voteList:
vote = map(int, vote)
minIndex = int(vote.index(min(vote)))
candidatePreferences.append(minIndex)
vote[minIndex] = 99999
return candidatePreferences
After converting string list to Int list you can perform min operation.
Please check and let me know.
Try this code. it fixed the error:
def countVotes(voteList):
candidatePreferences = []
for vote in voteList:
minIndex = int(vote.index(min(vote)))
candidatePreferences.append(minIndex)
vote[minIndex] = '99999'
return candidatePreferences
vList = [['1', '3', '4', '5', '2'], ['4', '2', '5', '3', '1'], ['1', '3', '2', '5', '4'], ['1', '2', '4', '3', '5'], ['1', '3', '4', '5', '2'], ['2', '1', '3', '5', '4'], ['1', '3', '4', '5', '2'], ['3', '5', '2', '4', '1'], ['1', '4', '5', '2', '3'], ['5', '1', '4', '3', '2'], ['3', '2', '5', '4', '1'], ['3', '1', '2', '5', '4'], ['2', '5', '1', '4', '3'], ['3', '2', '1', '4', '5'], ['4', '5', '3', '1', '2'], ['1', '5', '4', '3', '2'], ['1', '5', '3', '4', '2'], ['2', '1', '4', '3', '5'], ['4', '1', '2', '5', '3']]
cp = countVotes(vList)
print(str(cp))
output:
[0, 4, 0, 0, 0, 1, 0, 4, 0, 1, 4, 1, 2, 2, 3, 0, 0, 1, 1]
Convert string elements to integer.You can use python map function to convert all the list elements to integer
def countVotes(voteList):
candidatePreferences = []
for vote in voteList:
vote = list(map(int, vote)) # add this line to the code to convert string elements to integer
minIndex = int(vote.index(min(vote)))
candidatePreferences.append(minIndex)
vote[minIndex] = 99999
return candidatePreferences

Calculating element with most occurrences in list

I have
dict = {
0: ['9', '3', '3', '5', '1'],
1: ['9', '4', '1', '2'],
2: ['3', '4', '1', '5', '5'],
3: ['4', '4', '5', '5', '1'],
4: ['2', '8', '9', '5', '1']
}
take an example 0:['9', '3', '3', '5', '1'] here 3 has more number of occurance so iw ant to update enter list with only 3 so at index 0 becomes [3]
if every element has equal weight like 1: ['9', '4', '1', '2'] there will be no change
another ['4', '4', '5', '5', '1'] returns ['4','5']
i tried using collection.counter but donot know how to update the original dict with max repeated
for i,j in dictonary.items():
dictonary[i]=Counter(j)
expected output:
{0: ['3'], 1: ['9', '4', '1', '2'], 2: ['5'], 3: ['4'], 4: ['2', '8', '9', '5', '1']}
Edit: the list size may vary
[1,1,1,1,1,2,2,2,2,2,3,3,3]->[1,2]
[3,3,3,3,4,4,4,4,4,5,6,6,6,6,6]->[4,6]
from collections import *
d ={0: ['9', '3', '3', '5', '1'], 1: ['9', '4', '1', '2'], 2: ['3', '4', '1', '5', '5'], 3: ['4', '5', '0', '4', '3'], 4: ['2', '8', '9', '5', '1']}
for i,j in d.items():
c = Counter(j)
top = c.most_common(1)
if top[0][1] > 1:
d[i] = [ top[0][0] ]
print d
{0: ['3'], 1: ['9', '4', '1', '2'], 2: ['5'], 3: ['4'], 4: ['2', '8', '9', '5', '1']}
EDIT:
from collections import *
d = {
0: ['4', '4', '5', '5', '1'],
1: ['9', '4', '1', '2'],
2: ['3', '4', '1', '5', '5']
}
for i,j in d.items():
c = Counter(j)
result = []
for x in c:
if c[x] > 1:
result.append(x)
if result:
d[i] = result
print d
{0: ['5', '4'], 1: ['9', '4', '1', '2'], 2: ['5']}
EDIT:
from collections import *
d = {
0: ['4', '4', '5', '5', '1'],
1: [1,1,1,1,1,2,2,2,2,2,3,3,4],
2: ['3', '4', '1', '5', '5']
}
for i,j in d.items():
c = Counter(j)
longest = c.most_common(1)[0][1]
if longest > 1:
result = []
for x in c:
if c[x] == longest:
result.append(x)
d[i] = result
print d
{0: ['5', '4'], 1: [1, 2], 2: ['5']}
It appears you're looking for the mode of each element in your dictionary.
from collections import Counter
def mode(L):
result = []
for x in L:
if Counter(L)[x] == max(Counter(L).values()):
if x not in result: result.append(x)
return result
for item in dict:
dict[item] = mode(dict[item])

Categories