Hi I have a list of values
ls = ["a", "a", "b", "b", "b", "b", "c"]
And i wish to add an enumerating number to duplicates if ive used that term correctly.
Essentially I wnat to end up with this:
ls = ["a", "2a", "b", "2b", "3b", "4b", "c"]
or this
ls = ["1a", "2a", "1b", "2b", "3b", "4b", "1c"]
I just want each element of the list to be unique
This may not be the most effective way.
ls = ["a", "a", "b", "b", "b", "b", "c"]
UniqueValues = set(ls)
for x in UniqueValues:
number = 0
for i in range(0,len(ls)):
if ls[i] == x:
number += 1
if number >= 2:
ls[i] += str(number)
but we get what you're looking for
print(ls)
['a', 'a2', 'b', 'b2', 'b3', 'b4', 'c']
You can use Counter and unique methods.
from numpy import unique
from collections import Counter
ls = ["a", "a", "b", "b", "b", "b", "c"]
dup = dict(Counter(ls))
l_uniq = unique(ls)
print([key if i == 0 else key + str(i+1) for key in l_uniq for i in range(dup[key])])
Out:
['a', 'a2', 'b', 'b2', 'b3', 'b4', 'c']
So we need to check complete list each time so that if same value exists we can change the pointing value.
ls = ["a", "a", "b", "b", "b", "b", "c",'a','a']
for index,value in enumerate(ls):
if value in ls[index+1:]:
for new in range(0,200000000):
if not f'{value}{new}' in ls:
ls[index] = f'{value}{new}'
break
print(ls)
Output:
['a0', 'a1', 'b0', 'b1', 'b2', 'b', 'c', 'a2', 'a']
Related
I have two supplied bits of information: A dictionary of transactions and a list of the unique items in the transactions.
transactions = {
"T1": ["A", "B", "C", "E"],
"T2": ["A", "D", "E"],
"T3": ["B", "C", "E"],
"T4": ["B", "C", "D", "E"],
"T5": ["B", "D", "E"]
}
items = ["A", "B", "C", "D", "E"]
What I need to do is find the number of occurrences of these items in the transactions. I created a dictionary that has keys representing the unique items and the value for each key initialized to 0, but I am unsure of how to update these values to represent the number of occurrences in the transactions.
occurr = dict()
for x in items:
occurr[x] = 0
This is my occurrences dictionary which yields the output:
{'A': 0, 'B': 0, 'C': 0, 'D': 0, 'E': 0}
The final dictionary should look like:
{'A': 2, 'B':4, 'C': 3, 'D': 3, 'E': 5}
as 'A' occurs 2 times in the transactions, 'B' occurs 4 times, etc.
Well, you are in the right direction. You need to iterate over the values of dictionary.
occurr = dict()
for x in items:
occurr[x] = 0
for transaction in transactions.values():
for item in transaction:
occurr[item] += 1
Alternatively, you can concatenate all lists to single list and call collections.Counter:
import collections
items = [item for transaction in transactions.values() for item in transaction]
print(collections.Counter(items))
You can use Counter, for example:
from collections import Counter
transactions = {
"T1": ["A", "B", "C", "E"],
"T2": ["A", "D", "E"],
"T3": ["B", "C", "E"],
"T4": ["B", "C", "D", "E"],
"T5": ["B", "D", "E"]
}
c = Counter()
for dd in transactions.values():
c.update(dd)
print(c) # or c.items(), c.keys() or c.values()
# Result: Counter({'E': 5, 'B': 4, 'C': 3, 'D': 3, 'A': 2})
# Note that the result is a subclass of dict
This will count the frequency of all values in transactions. If you need to restrict to those keys present in items then filter for that.
Alternatively, flatten the transaction list values into a single list, and count that in one call. For example:
flatlist = [item for sublist in transactions.values() for item in sublist]
print(Counter(flatlist))
Try:
transactions = {
"T1": ["A", "B", "C", "E"],
"T2": ["A", "D", "E"],
"T3": ["B", "C", "E"],
"T4": ["B", "C", "D", "E"],
"T5": ["B", "D", "E"],
}
items = ["A", "B", "C", "D", "E"]
out = {}
for l in transactions.values():
for v in l:
out[v] = out.get(v, 0) + 1
out= {k: out.get(k) for k in items}
print(out)
Prints:
{'A': 2, 'B': 4, 'C': 3, 'D': 3, 'E': 5}
Take this dictionary for example,
d = {
1: ["a", "b"],
2: ["c", "d"],
3: ["e", 1]
}
What I want to do is something like this:
for i in d:
if any(i in j for j in d.values()): # if a key of d exists in any of the lists
'add values of i to the list that had i in it'
So d would then look like:
d = {
1: ["a", "b"],
2: ["c", "d"],
3: ["e", 1, "a", "b"]
}
I understand this can be simply done with a nested for loop, but is there any way with list comprehension?
I am not sure how to do this with a list comprehension, however,this is how I would do it with nested for-loops:
Code:
d = {
1: ["a", "b"],
2: ["c", "d"],
3: ["e", 1]
}
for k,v in d.items():
for i in v:
if i in d.keys():
d[k] = d[k] + d[i]
print(d)
Output:
{1: ['a', 'b'], 2: ['c', 'd'], 3: ['e', 1, 'a', 'b']}
Keep it simple. There may be a way to do this using a list comprehension but it would be highly esoteric and (potentially) hard to understand.
d = {
1: ["a", "b"],
2: ["c", "d"],
3: ["e", 1]
}
for v in d.values():
for e in v:
if (_v := d.get(e)):
v += _v
print(d)
Output:
{1: ['a', 'b'], 2: ['c', 'd'], 3: ['e', 1, 'a', 'b']}
I have a list like this:
some = [["a", "1", "c"], ["a", "2", "#"], ["b", "1", "9"], ["c", "1", "pw"], ["c", "2", "af"]]
The list is ordered based on second column. So all rows are sorted here. I am trying the split the list into the n different lists based on unique values. I tried the following
import pandas as pd
uniquevals = pd.DataFrame(some)[0].value_counts()
newlist = []
for i in uniquevals:
newlist = some[1:i]
print(newlist)
print("Done\n")
and the result is
[['a', '2', '#']]
Done
[['a', '2', '#']]
Done
[]
Done
But ideally, I want rows in the column to split based on the count of unique values of first column. Here a has two values and b has one value and c has two values. Ideal output should be:
[["a", "1", "c"], ["a", "2", "#"]]
Done
[["b", "1", "9"]]
Done
[["c", "1", "pw"], ["c", "2", "af"]]
Done
Why not just use pd.DataFrame.groupby:
some = [["a", "1", "c"], ["a", "2", "#"], ["b", "1", "9"], ["c", "1", "pw"], ["c", "2", "af"]]
uniquevals = pd.DataFrame(some)
for _, i in uniquevals.groupby(0):
print(i.to_numpy().tolist())
print("Done\n")
Output:
[['a', '1', 'c'], ['a', '2', '#']]
Done
[['b', '1', '9']]
Done
[['c', '1', 'pw'], ['c', '2', 'af']]
Done
I have a dict I wish to make which will be quite big, 600 key value pairs. The keys will be integers, the values will be from a list of 3 letters (A,B and C). If I generate a list of the keys how can I 'map' the appropriate value to the key.
Code
my_list = list(range(1,11,1))
my_letters = ["A", "B", "C"]
my_dict = {}
for k in my_list:
for v in my_letters
# I know it isn't going to be nested for loops
Desired output
#my_dict = {"1" : "A", "2" : "B", "3" : "C", "4" : "A", ... "10" : "A"}
Here you can access the corresponding value in my_letters by using the remainder of the division of the key by the length of the list of letters.
my_list = list(range(1,11,1))
my_letters = ["A", "B", "C"]
my_dict = {}
for k in my_list:
my_dict[k] = my_letters[k%len(my_letters)-1]
print(my_dict)
Output:
{1: 'A', 2: 'B', 3: 'C', 4: 'A', 5: 'B', 6: 'C', 7: 'A', 8: 'B', 9: 'C', 10: 'A'}
As pointed out by #DarryIG, using dict comprehension:
my_letters = ["A", "B", "C"]
my_dict = {k:my_letters[k%len(my_letters)-1] for k in range(1, 11)}
You can use itertools.cycle to loop over the shorter list and the range object together with zip, and create the dictionary with dict comprehensions
my_dict = {x: z for x, z in zip(range(1, 11), itertools.cycle(["A", "B", "C"]))}
print(my_dict) # {1: 'A', 2: 'B', 3: 'C', 4: 'A', 5: 'B', 6: 'C', 7: 'A', 8: 'B', 9: 'C', 10: 'A'}
As a side note, no need to convert range to list or to specify step in range if it's 1.
I would like to know is there an "easy" way to create two matching arrays inserting some dummy missing value in both arrays so they remain same size and indexes that are the same in both arrays remain the same, so for example:
["A", "B", "C", "D", "E", "F"] and ["B", "C", "E"]
Would be
["A", "B", "C", "D", "E", "F"] and ["N/A", "B", "C", "N/A", "E", "N/A"]
Thanks in advance :-)
One-liner in a list comprehension to do this:
array_1 = ["A", "B", "C", "D", "E", "F"]
array_2 = {"B", "C", "E"}
array_3 = [x if x in array_2 else "N/A" for x in array_1]
print(array_3)
result:
['N/A', 'B', 'C', 'N/A', 'E', 'N/A']
Note that I converted array_2 to a set for quicker lookup.
array_1 = ["A", "B", "C", "D", "E", "F"]
array_2 = ["B", "C", "E"]
array_3 = array_1
for n,x in enumerate(array_3):
if x not in array_2:
array_3[n] = np.nan
print (array_3)
out:
[nan, 'B', 'C', nan, 'E', nan]