Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have this function that returns the list of values and counts for integer values. I would like to alter this to return the counts and values of strings, as I am having trouble implementing. It works for integer values but not strings.
def frequencies(xs):
ys = sorted(xs)
values, count = [], []
for y in ys:
if y not in values:
values.append(y)
count.append(1)
else:
count[-1] += 1
return values, count
using itertools.groupby:
>>> import itertools
>>> a = [1,2,3,4,5,6,2,3,4,5,3,7,8,4,5,6,3]
>>> [ [x,len(list(y))] for x,y in itertools.groupby(sorted(a))] # if you want list
[[1, 1], [2, 2], [3, 4], [4, 3], [5, 3], [6, 2], [7, 1], [8, 1]]
>>> {x:len(list(y)) for x,y in itertools.groupby(sorted(a))} # if you want dictionary
{1: 1, 2: 2, 3: 4, 4: 3, 5: 3, 6: 2, 7: 1, 8: 1}
Why reinvent the wheel, and not use Counter? From what I understand, you try to achieve exactly what Counter does.
from collections import Counter
a = Counter([1,2,3,2,3,4,5,3,4,3,4,2,1,2,5])
print(a.keys(), a.values())
b = Counter(["1","2","3","2","3","4","5","3","4",'3','4','2','1','2','5'])
print(b.keys(), b.values())
Gives:
dict_keys([1, 2, 3, 4, 5]) dict_values([2, 4, 4, 3, 2])
dict_keys(['4', '2', '3', '1', '5']) dict_values([3, 4, 4, 2, 2])
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Improve this question
So I'm trying to find the items that went in and went out of a list before and after it changed
For example, at first my list is:
[1, 1, 2, 5, 7, 7]
And then a minute later it's:
[1, 2, 2, 5, 6, 7, 4]
How would I end up with 2 lists that show what items went out and which went in like so,
itemsOut = [1,7]
itemsIn = [2, 6, 4]
Position and length can change
You can use Counter from the built-in collections module:
>>> list1 = [1, 1, 2, 5, 7, 7]
>>> list2 = [1, 2, 2, 5, 6, 7, 4]
>>> from collections import Counter
>>> counter1 = Counter(list1)
>>> counter2 = Counter(list2)
>>> l_diff = counter1-counter2
>>> r_diff = counter2-counter1
>>> print(list(l_diff))
[1, 7]
>>> print(list(r_diff))
[2, 6, 4]
You could use something like this, to detect wich items changed.
old_arr = [1, 2, 2, 5, 7, 7]
new_arr = [1, 1, 2, 5, 7, 7]
items_out = []
for element in old_arr:
if new_arr.count(element) > 0:
new_arr.pop(new_arr.index(element))
else:
items_out.append(element)
print("Items out:", items_out)
print("Items in:", new_arr)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I am trying to count how many numbers appear in each row in a 2d list and then return the values with a new variable . For example, I would to like to return the items that are greater than or equal to that length.
Here my list below
df = [[2,4,6,7],[3,4,],[2,4,6,8,12,24],[3,5,7,333,450],[4,20]]
I would like to create a new variable and return each row that is longer than 3.
df2 =[[2,4,6,7],[2,4,6,8,12,24],[3,5,7,333,450]]
I would like to create a new variable and return each row with exactly 2 elements.
df3 = [[3,4,],[4,20]]
Probably not the most efficient solution but a succinct way to do this:
df = [[2,4,6,7],[3,4,],[2,4,6,8,12,24],[3,5,7,333,450],[4,20]]
df3 = filter(lambda l: len(l) > 3, df)
df2 = filter(lambda l: len(l) == 2, df)
print(list(df2))
print(list(df3))
output:
[[3, 4], [4, 20]]
[[2, 4, 6, 7], [2, 4, 6, 8, 12, 24], [3, 5, 7, 333, 450]]
You can use list comprehensions to do this. In this case, you can check the len of each sublist, and use that to filter out which sublists you want to keep/discard.
>>> df = [[2,4,6,7],[3,4,],[2,4,6,8,12,24],[3,5,7,333,450],[4,20]]
>>> [i for i in df if len(i) > 3]
[[2, 4, 6, 7], [2, 4, 6, 8, 12, 24], [3, 5, 7, 333, 450]]
>>> [i for i in df if len(i) == 2]
[[3, 4], [4, 20]]
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I want to replace variables in a list with combination of elements.
To be more specific:
I have these two lists
liste1 = [1,2,3,'X','X',4]
liste2 = [5,6,7]
and I want to get a list containing the elements below :
[1,2,3,5,6,4]
[1,2,3,5,7,4]
[1,2,3,6,7,4]
[1,2,3,6,5,4]
[1,2,3,7,5,4]
[1,2,3,7,6,4]
Does anyone have an idea how to make it ?
You can do it this way:
from itertools import permutations
liste1 = [1, 2, 3, 'X', 'X', 4]
liste2 = [5, 6, 7]
def replacements(liste1, liste2):
x_indices = [i for i, val in enumerate(liste1) if val == 'X']
nb = len(x_indices)
for perm in permutations(liste2, nb):
l1 = liste1[:] # if we want to preserve the original and yield different lists
for i, new_val in zip(x_indices, perm):
l1[i] = new_val
yield l1
for r in replacements(liste1, liste2):
print(r)
Output:
[1, 2, 3, 5, 6, 4]
[1, 2, 3, 5, 7, 4]
[1, 2, 3, 6, 5, 4]
[1, 2, 3, 6, 7, 4]
[1, 2, 3, 7, 5, 4]
[1, 2, 3, 7, 6, 4]
We first list the indices where 'X' appears, then generate the permutations of as many elements of liste2. For each permutation, we replace the 'X's.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have two lists say:
a = [1, 2, 2, 2, 3]
b = [2, 5, 6]
After doing a union, I should get something like this (don't mind the order):
c = [1, 2, 2, 2, 3, 5, 6]
The final list should contain common elements only once and rest of elements (from both lists) should be copied as they are. Sets can't be used for this as they remove multiple occurrence of an element from the list, which isn't a union. What is a Pythonic way to do so?
Perform a union, keeping repetition:
>>> c = a + b
[1, 2, 2, 3, 2, 5, 6]
Perform a union, keeping repetition & order:
>>> c = sorted(a + b)
[1, 2, 2, 2, 3, 5, 6]
Perform an union, no repetition in each list, but repetition allowed in final union, and keeped order:
>>> c = sorted(list(set(a)) + list(set(b)))
[1, 2, 2, 3, 5, 6]
After clarification of the question, the goal is to build a list that take elements (including repetition) of, and then add elements of b if they are not in the new list.
>>> c = a + [e for e in b if e not in a]
[1, 2, 2, 2, 3, 5, 6]
After another clarification of the question, the goal is to build a list containing all elements of input list. But, if elements are in common, they are pushed the same number there
>>> from collections import Counter
>>> def merge(a,b):
... na, nb = Counter(a), Counter(b)
... return list(Counter({k: max((na[k], nb[k])) for k in set(a + b)}).elements())
>>> merge([1, 2, 2, 2, 3], [2, 5, 6])
[1, 2, 2, 2, 3, 5, 6]
>>> merge([1, 2, 3], [2, 2, 4])
[1, 2, 2, 4]
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have two lists:
X=[[1,2,3],[5,5],[1]]
Y=[[2,4],[1,4,6,6],[1,3]]
There is a one-one correspondence between the elements of lists X and Y. I want to sort the elements of X by the length of items, and at the same time the items of Y be sorted in the correct position by the new indices of X's items.
The result should be:
X=[[1],[5,5],[1,2,3]]
Y=[[1,3],[1,4,6,6],[2,4]]
There is a one-one correspondence between the elements of lists X and Y
This suggests that you should zip the lists together before you do anything else to them.
>>> zippedLists = zip(X, Y)
zippedLists will be a list of tuples containing corresponding elements from X and Y:
>>> list(zippedLists)
[([1, 2, 3], [2, 4]), ([5, 5], [1, 4, 6, 6]), ([1], [1, 3])]
Now you can rearrange the tuples according to the length of the first element, using the key argument to sorted:
>>> sortedZippedLists = sorted(zippedLists, key=lambda x: len(x[0]))
>>> list(sortedZippedLists)
[([1], [1, 3]), ([5, 5], [1, 4, 6, 6]), ([1, 2, 3], [2, 4])]
And then unzip the lists, if you need to.
>>> sortedX, sortedY = zip(*sortedZippedLists)
>>> list(sortedX)
[[1], [5, 5], [1, 2, 3]]
>>> list(sortedY)
[[1, 3], [1, 4, 6, 6], [2, 4]]
Or, as a single expression:
zip(*sorted(zip(X,Y), key=lambda x: len(x[0])))
A Baroque Solution
[Y[i] for i in list(zip(*sorted(zip(X, range(len(X))), key=lambda x:len(x[0]))))[1]]
Does It Works?
In [6]: X
Out[6]: [[1, 2, 3], [5, 5], [1]]
In [7]: Y
Out[7]: [[2, 4], [1, 4, 6, 6], [1, 3]]
In [8]: [Y[i] for i in list(zip(*sorted(zip(X, range(len(X))), key=lambda x:len(x[0]))))[1]]
Out[8]: [[1, 3], [1, 4, 6, 6], [2, 4]]