This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 6 years ago.
My code should recieve a list of numbers and then output on the screen the only numbers which repeat more then once. I don't know why but it don't work with the numbers in the middle of list. My code:
a = [int(i) for i in (input().split())]
a.sort()
for number in a:
if a.count(number)==1:
a.remove(number)
else:
a.remove(a.count(number)-a.count(number)+number)
for number in a:
print(number, end=' ')
I tried changing if on while on 4th string, but then the last number is left in the list.
It should work like:
Sample Input 1: 4 8 0 3 4 2 0 3 Sample Output 1: 0 3 4
Sample Input 2: 10 Sample Output 2:
Sample Input 3: 1 1 2 2 3 3 Sample Output 3: 1 2 3
Sample Input 4: 1 1 1 1 1 2 2 2 Sample Output 4: 1 2
You could approach this problem using set instead:
a = list(map(int, input().split()))
print(" ".join(map(str, set(i for i in a if a.count(i) > 1))))
Explanation:
Firstly, it looks like you should read up on the map function. Instead of a = [int(i) for i in (input().split())], you can just use list(map(int, input().split())), which is much more Pythonic.
Secondly, the important part of the second line is set(i for i in a if a.count(i) > 1), which just creates a new list containing only the duplicates from a (i.e. [1, 2, 3, 2, 3] becomes [2, 3, 2, 3] and then applies set to it, which converts [2, 3, 2, 3] into {2, 3} (which is a set object).
In case you're wondering what map(str, ...) is for, it's so that you can print each of the elements inside your new set (e.g. {2, 3}).
You can use built-in lib collections to count list items and filter it by a required condition.
import collections
ints = map(int, input().split())
count = collections.Counter(ints)
print filter(lambda x: count[x] > 1, count)
Related
This question already has answers here:
How to zip two differently sized lists, repeating the shorter list?
(15 answers)
Closed 7 months ago.
I have 2 lists of a different length
list_1 = [1, 2, 3, 4, 5]
list_2 = ['a', 'b']
If I'd do:
for (i,j) in itertools.zip_longest(list_1, list_2):
print (i,j)
The output would be
1 a
2 b
3 None
4 None
5 None
What I want is to iterate over those 2 lists, but repeat the shorter list when it gets exhausted any amount of times while the longer list still iterates. In this example I'd want output to be
1 a
2 b
3 a
4 b
5 a
There's an itertools for that. You want to cycle the second list and do a vanilla zip on the first. cycle will remember and reemit values from list_2 and zip will stop at the end of list_1.
>>> import itertools
>>> list_1 = [1, 2, 3, 4, 5]
>>> list_2 = ['a', 'b']
>>> for i,j in zip(list_1, itertools.cycle(list_2)):
... print(i, j)
...
1 a
2 b
3 a
4 b
5 a
if you want the result to always be the longer of the two lists (either could cycle), you'd need to choose which one uses itertools.cycle. There are a dozen ways to do that, but here's one
>>> zipper = zip(list_1, itertools.cycle(list_2)) if len(list_1) >= len(list_2) else zip(itertools.cycle(list_1), list_2)
>>> for i, j in zipper:
... print(i, j)
...
1 a
2 b
3 a
4 b
5 a
And if you want something that works for iterators in general (they wouldn't know their size in advance), you could make them into a list first.
I need to code a script that chooses a number from a user input (list) depending on two conditions:
Is a multiple of 3
Is the smallest of all numbers
Here is what I've done so far
if a % 3 == 0 and a < b:
print (a)
a = int(input())
r = list(map(int, input().split()))
result(a, r)
The problem is I need to create a loop that keeps verifying these conditions for the (x) number of inputs.
It looks like you want a to be values within r rather than its own input. Here's an example of iterating through r and checking which numbers are multiples of 3, and of finding the minimum of all the numbers (not necessarily only those which are multiples of 3):
r = list(map(int, input().split()))
for a in r:
if a % 3 == 0:
print(f"Multiple of 3: {a}")
print(f"Smallest of numbers: {min(r)}")
1 2 3 4 5 6 7 8 9 0
Multiple of 3: 3
Multiple of 3: 6
Multiple of 3: 9
Multiple of 3: 0
Smallest of numbers: 0
Doing this in one line – or through generators – can improve performance through optimizing memory allocation:
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# The following is a generator
# Also: you need to decide if you want 0 to be included
all_threes = (x for x in my_list if x%3==0)
min_number = min(my_list)
This question already has answers here:
Index of duplicates items in a python list
(21 answers)
Closed 1 year ago.
nums = [11, 2,4, 2, 5]
for i in nums:
print(nums.index(i),i )
I run the above code and it uses same index for similar elements(here 2 at index 1 and 3).
I wasn't aware of this python list behavior, does it mean the use of lists can be restrictive for similar elements in same list?
The index() method returns the position at the first occurrence of the specified value.
So it returns first index of number 2.
nums = [11, 2,4, 2, 5]
You can enumerate() to get all indexes.
nums = [11, 2,4, 2, 5]
for i,n in enumerate(nums):
print(i, n)
0 11
1 2
2 4
3 2
4 5
How to code a program that shows me the item that appears most side-by-side?
Example:
6 1 6 4 4 4 6 6
I want four, not six, because there are only two sixes together.
This is what I tried (from comments):
c = int(input())
h = []
for c in range(c):
h.append(int(input()))
final = []
n = 0
for x in range(c-1):
c = x
if h[x] == h[x+1]:
n+=1
while h[x] != h[c]:
n+=1
final.append([h[c],n])
print(final)
Depends on what exactly you want for an input like
lst = [1, 1, 1, 2, 2, 2, 2, 1, 1, 1]
If you consider the four 2 the most common, because it's the longest unbroken stretch of same items, then you can groupby same values and pick the one with max len:
max((len(list(g)), k) for k, g in itertools.groupby(lst))
# (4, 2) # meaning 2 appeared 4 times
If you are interested in the element that appears the most often next to itself, you can zip the list to get pairs of adjacent items, filter those that are same, pass them through a Counter, and get the most_common:
collections.Counter((x,y) for (x,y) in zip(lst, lst[1:]) if x == y).most_common(1)
# [((1, 1), 4)] # meaning (1,1) appeared 4 times
For your example of 6 1 6 4 4 4 6 6, both will return 4.
maxcount=0; //store maximum number item side by side
num=-1; //store element with max count
for i=0 to n //loop through your array
count=0;
in=i;
while(arr[in++]==arr[i]){//count number of side by side same element
count++;
}
maxcount=max(maxcount,count);
num= maxcount==count? arr[i]:num;
i=in-1;
endfor;
I'm banging my head against the wall trying to figure out why this nested loop is miscounting the number of times an integer occurs in a list. I've set up a function to take two lines of input, n and ar, where n is the number of integers in ar and ar is the list of integers. My code is below:
import sys
n = sys.stdin.readline()
n = int(n)
ar = sys.stdin.readline()
ar = ar.split(' ')
ar = [int(i) for i in ar]
def find_mode(n,ar):
# create an empty dict and initially set count of all integers to 1
d = {}
for i in range(n):
d[ar[i]] = 1
for i in range(n):
# hold integer i constant and check subsequent integers against it
# increase count if match
x = ar[i]
for k in range(i+1,n):
if ar[k] == x:
d[ar[k]] += 1
print(d)
The counter seems to be increasing the count by 1 every time, which leads me to believe it's a problem with the nested loop.
>>> 9
>>> 1 2 3 4 4 9 9 0 0
{0: 2, 1: 1, 2: 1, 3: 1, 4: 2, 9: 2}
OK
>>> 10
>>> 1 2 3 4 4 9 9 0 0 0
{0: 4, 1: 1, 2: 1, 3: 1, 4: 2, 9: 2}
Count of 0 increased by +2
>>> 11
>>> 1 2 3 4 4 9 9 0 0 0 0
{0: 7, 1: 1, 2: 1, 3: 1, 4: 2, 9: 2}
Count of 0 increased by +3
I understand there might be more efficient or "pythonic" ways to count the amount of times a number occurs in a list but this was the solution I came up with and as someone still learning Python, it would help to understand why this exact solution is failing. Many thanks in advance.
This is because for each distinct number in the list (call it x) you count the number of subsequent appearances. This is fine if a number only occurs twice but if it occurs multiple times you will over-count for each additional appearance.
For example: [0, 0, 0, 0]. You iterate over the list and then for each item you iterate over the list that follows that item. So for the first 0 you count a total of 3 subsequent 0s. For the second however you will count a total of 2 and for the third a total of 1 which makes 6. This is why you have 3 too much in the end.
You can achieve this task by using collections.Counter:
>>> from collections import Counter
>>> d = Counter(ar)
I'm not exactly sure that I can fix your specific problem, but would something like this work instead?
d={}
for x in ar:
d[x] = d.get(x, 0) + 1
I understand that you want to fix your existing work as a learning exercise, but I'm not sure that that approach is even the right one. As it is, I can't really tell what you're going for, so it's hard for me to offer specific advice. I would recommend that you don't throw good time after bad.
python has a method to do exactly what you're describing.
It's called .count().
If you do ar.count(3), it will return the number of occurences of 3 in the list ar.
** In your case:**
There's no need for a nested loop as you only need one loop.
Try this:
dic = {}
for num in ar:
if num not in dic:
dic[num] = 1
else:
dic[num] += 1
This would produce the dict you want with the numbers and their occurences
You can refer to other answers as to how you should solve this problem more efficiently, but to answer the question you're asking (Why doesn't this nested loop work?):
To visualize what your nested loop is doing consider the following input:
0 0 0 0 0
Your algorithm will count the following:
0 0 0 0 0
^ ^ ^ ^ ^ (5)
then,
0 0 0 0 0
^ ^ ^ ^ (4)
then,
0 0 0 0 0
^ ^ ^ (3)
then,
0 0 0 0 0
^ ^ (2)
and finally,
0 0 0 0 0
^ (1)
What happens is it counts the number of 0's multiple times over. In this instance it will count
15 0's (5+4+3+2+1)
itertools are your friend
from itertools import groupby
def group_by_kv_l(n):
l = []
for k, v in groupby(n):
l.append((len(list(v)),int(k)))
return l
def group_by_kv_d(n):
d = {}
for k, v in groupby(n):
d[(int(k))] = len(list(v))
return d
if __name__ == "__main__":
n = input().split()
n = "".join(n)
print(
"STDIN: {}".format(n)
)
print(
group_by_kv_l(n)
)
print(
group_by_kv_d(n)
)