Compare two arrays and their elements against one another - python

How do i covert this into a Python code. I dont get how to do the compare between players and the winNum. The players is a 2D array and winNum is a 1D array.
below is a sample data set that i have been using
in the function what im trying to achive is that for every player in players i want to compare all their numbers with the winNum numbers and find if they match and if they do match i want to make 1 increment to the count. Both arrays have 8 elements and they are sorted from 0-6 and 6-8.
winNum = [0, 5, 20, 22, 23, 25, 0, 26]
player = [[0, 5, 20, 22, 23, 25, 0, 26],[14, 15, 21, 25, 26, 29, 30, 30],[3, 6, 8, 16, 25, 30, 0, 13]]
for i in range (len(player)):
for j in range(6):
x = player[i][j]
and compare with winNum[](0-6)
if x is in winNum:
count +=c1
and move on to the next number
else
ignore and move on to the next number

You could try the following code:
count=0
for i in range(len(player)):
for j in range(8):
x = player[i][j]
if x in winNum:
count+=1
You could also store the 'count' further by appending it to a new empty list. I wasn't sure if you wanted that too, but doing that is also straight forward.
count_list = []
for i in range(len(player)):
count=0
for j in range(8):
x = player[i][j]
if x in winNum:
count+=1
count_list.append(count)

Related

Find first and last integers in a list of series of numbers

I'm working with lists that look as follows:
[2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,30,31,32,33,34,35]
In the end I want to extract only the first and last integer in a consecutive series, as such:
[(2,8),(13,20),(30,35)]
I am new to working with Python, below my code for trying to solve this problem
helix = []
single_prot_helices = []
for ind,pos in enumerate(prot[:-1]):
if pos == prot[ind+1]-1: #if 2 == 3-1 essentially
helix.append(pos)
elif pos < prot[ind+1]-1: #if 8 < 13-1 for example
helix.append(pos)
single_prot_helices.append(helix) #save in a permanent list, clear temp list
helix.clear()
In this case prot is a list just like the example above. I expected single_prot_helices to look something like this:
[[2,3,4,5,6,7,8],[13,14,15,16,17,18,19,20],[30,31,32,33,34,35]]
and at this point it would have been easy to get the first and last integer from these lists and put them in a tuple, but instead of the expected list I got:
[[20,30,31,32,33,34,35],[20,30,31,32,33,34,35]]
Only the last series of numbers was returned and I got 1 less lists than expected (expected 3, received 2). I don't understand where I made a mistake since I believe my code follows my logic: look at the number (pos), look at the next number, if the next number is larger by 1 then add the number (pos) to a list (helix); if the next number is larger by more than 1 then add the smaller number (pos) to the list (helix), append the list to a permanent list (single_prot_helices) and then clear the list (helix) to prepare it for the next series of numbers to be appended.
Any help will be highly appreciated.
You could do something like this:
foo = [2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,30,31,32,33,34,35]
series = []
result = []
for i in foo:
# if the series is empty or the element is consecutive
if (not series) or (series[-1] == i - 1):
series.append(i)
else:
# append a tuple of the first and last item of the series
result.append((series[0], series[-1]))
series = [i]
# needed in case foo is empty
if series:
result.append((series[0], series[-1]))
print(result) # [(2, 8), (13, 20), (30, 35)]
Or, as a generator:
def generate_series(list_of_int):
series = []
for i in list_of_int:
if not series or series[-1] == i - 1:
series.append(i)
else:
yield (series[0], series[-1])
series = [i]
if series:
yield (series[0], series[-1])
foo = [2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,30,31,32,33,34,35]
print([item for item in generate_series(foo)]) # [(2, 8), (13, 20), (30, 35)]
Yours has a few problems.
The main one is that helix is a mutable list and you only ever clear it. This is causing you to append the same list multiple times which is why they're all identical.
The first fix is to assign a new list to helix rather than clearing.
prot = [2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,30,31,32,33,34,35]
helix = []
single_prot_helices = []
for ind,pos in enumerate(prot[:-1]):
if pos == prot[ind+1]-1: #if 2 == 3-1 essentially
helix.append(pos)
elif pos < prot[ind+1]-1: #if 8 < 13-1 for example
helix.append(pos)
single_prot_helices.append(helix) #save in a permanent list, clear temp list
helix = []
print(single_prot_helices) # [[2, 3, 4, 5, 6, 7, 8], [13, 14, 15, 16, 17, 18, 19, 20]]
As you can see the last list is missed. That is because the last helix is never appended.
You could add:
if helix:
single_prot_helices.append(helix)
But that still only gives you:
[[2, 3, 4, 5, 6, 7, 8], [13, 14, 15, 16, 17, 18, 19, 20], [30, 31, 32, 33, 34]]
leaving out the last element since you only ever iterate to the second from last one.
Which means you would need to do something complicated and confusing like this outside of your loop:
if helix:
if helix[-1] == prot[-1] - 1:
helix.append(prot[-1])
single_prot_helices.append(helix)
else:
single_prot_helices.append(helix)
single_prot_helices.append(prot[-1])
else:
single_prot_helices.append(prot[-1])
Giving you:
[[2, 3, 4, 5, 6, 7, 8], [13, 14, 15, 16, 17, 18, 19, 20], [30, 31, 32, 33, 34, 35]]
If you're still confused by names and mutability Ned Batchelder does a wonderful job of explaining the concepts with visual aids.
You can try this one that uses zip().
res = []
l, u = prot[0], -1
for x, y in zip(prot, prot[1:]):
if y-x > 1:
res.append((l, x))
u, l = x, y
res.append((l, prot[-1])) # [(2, 8), (13, 20), (30, 35)]
The solution of #Axe319 works but it doesn't explain what is happening with your code.
The best way to copy data from a list is by using copy(), otherwise you will copy its pointer.
When you add helix to single_prot_helices you will add a pointer of that list so you will have:
# helix = [2, 3, 4, 5, 6, 7, 8]
# single_prot_helices = [[2, 3, 4, 5, 6, 7, 8]]
And when you do helix.clear() you will have:
# helix = []
# single_prot_helices = [[]]
Why ? Because in single_prot_helices you added the pointer and not the elements of that list.
After the second iteration you will have
# helix = [13, 14, 15, 16, 17, 18, 19, 20]
# single_prot_helices = [[13, 14, 15, 16, 17, 18, 19, 20], [13, 14, 15, 16, 17, 18, 19, 20]]
Why two lists in single_prot_helices ? Because you added a second pointer to the list, and first was still there.
Add some prints to your code to understand it well. Note that I added 40, 41 in the list so that you can have better visualisation:
prot = [2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,30,31,32,33,34,35,40, 41]
helix = []
single_prot_helices = []
for ind,pos in enumerate(prot[:-1]):
if pos == prot[ind+1]-1: #if 2 == 3-1 essentially
helix.append(pos)
elif pos < prot[ind+1]-1: #if 8 < 13-1 for example
helix.append(pos)
print("helix")
print(helix)
single_prot_helices.append(helix) #save in a permanent list, clear temp list
print(single_prot_helices)
helix.clear()
print("clear")
print(helix)
print(single_prot_helices)
In a single line
data = [2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,30,31,32,33,34,35]
mask = iter(data[:1] + sum(([i1, i2] for i1, i2 in zip(data, data[1:] + data[:1]) if i2 != i1+1), []))
print (list(zip(mask, mask)))
Gives #
[(2, 8), (13, 20), (30, 35)]
Functional approch
Using groupby and count from itertools considering taking diffrence between index and item if they are same group accordingly. Count them uisng ittertools counter - counter
data = [2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,30,31,32,33,34,35]
from itertools import groupby, count
final = []
c = count()
for key, group in groupby(data, key = lambda x: x-next(c)):
block = list(group)
final.append((block[0], block[-1]))
print(final)
Also gives #
[(2, 8), (13, 20), (30, 35)]

Python -- Find a sequence of numbers in triplets, quadruplets or more:

So, in my problem i have a list of numbers,i.e:
[0, 10, 11, 12, 24, 26, 28, 30, 31]
and i want to find a sequence of consecutive numbers in this list, in this case [10, 11, 12] my desired output is a tuple telling me the position of the first number in this sequence and how many numbers are in the sequence, generalized for a sequence of N numbers.
the output for the given sequence is equal to (2,3)
I've tried something like for sequences of 3:
#sequence of 3
for i in range(len(b)-3):
if i>=2 and b[i]==b[i+1] and b[i]==b[i+2] and b[i]!=b[i-1] and b[i]!=b[i+3]:
count_seq_3 += 1
position_3= i
print(position_3, count_seq_3)
The given output is (0,0) anyone could please help me in what is wrong? thanks in advance!!
list = [0, 10, 11, 12, 24, 26, 28, 30, 31]
sequence = []
for i in range(len(list)-2):
if list[i] == list[i+1] - 1 or list[i] == list[i-1] + 1:
sequence.append(list[i])
print((list.index(sequence[0]), len(sequence)))
The actual output is:
(1, 3)
Where 1 is index of starting element 10 in your list and 3 is length of your sequence.

Python, Compare a list of numbers and continually loop until there's no duplicates

I'm trying to create a simple script that will help me for network planning.
I have a list of numbers--
subnets = [21, 21, 21, 19, 20, 23, 23]
For every duplicate, I'm looking to replace 2 duplicated numbers with a new number that's minus 1. For example, replace (2) of the 21s with a 20. Replace (2) 23s with a 22, and so on.
I've got--
x = sorted(subnets)
z = []
for a in x:
if a not in z:
z.append(a)
else:
z.remove(a)
z.append(a-1)
print(z)
That kinda gets me what I want--
[19, 20, 20, 21, 22]
but there's (2) 20s in my final output, and that needs to be replaced with a 19, and then the (2) remaining 19s need to be replaced with an 18.
How do I continually loop my logic here?
My final output should be [18, 21, 22]
this below code gets me what I want, but it's nasty and I'm not going to know how many for loops to use as my subnets list changes, if I've got an additional 10 numbers in the subnets list, I don't want to have to change the script every time to keep creating these for loops
subnets = [21, 21, 21, 19, 20, 23, 23]
x = sorted(subnets)
z = []
y = []
v = []
for a in x:
if a not in z:
z.append(a)
else:
z.remove(a)
z.append(a-1)
for a in z:
if a not in y:
y.append(a)
else:
y.remove(a)
y.append(a-1)
for a in y:
if a not in v:
v.append(a)
else:
v.remove(a)
v.append(a-1)
print(v)
The following solution may be suboptimal in terms of performance, but it seems easy to understand. You need a Counter object from the standard Python library that counts duplicate objects in a list.
subnets = [21, 21, 21, 19, 20, 23, 23]
from collections import Counter
The loop goes for as long as there are duplicates - that is, the length of the set of items is smaller than the length of the list of items (sets eliminate duplicates).
while len(subnets) > len(set(subnets)):
# [v-1] * (cnt // 2) - even # of duplicates
# [v] * (cnt % 2) - odd remaining non-duplicate
# sum() rebuilds the list from the sublists
subnets = sum([[v-1] * (cnt // 2) + [v] * (cnt % 2)
for v, cnt in Counter(subnets).items()], [])
# [18, 21, 22]
This is similar to your idea, we just run the replacement operation in a while loop, modifying a list in-place:
def replace_pairs_minus_one(inp):
l = inp[:]
while(True):
for i, e in enumerate(l):
if e in l[i+1:]:
# pair found
# here we modify the list, since we are breaking anyway
l[i] = e - 1
l.remove(e)
break
else:
# break out of while if no pairs found
break
return sorted(l)
subnets = [21, 21, 21, 19, 20, 23, 23]
pairs_removed = replace_pairs_minus_one(subnets) # [18, 21, 22]

Printing element in array python problems

I want to go through each element of an array I've created. However, I'm doing some debugging and it's not. Here's what I have so far and what it's printing out.
def prob_thirteen(self):
#create array of numbers 2-30
xcoords = [range(2,31)]
ycoords = []
for i in range(len(xcoords)):
print 'i:', xcoords[i]
output:
i: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
Why does 'i' return my whole array and not just the first element: 2? I'm not sure why this is returning my whole array.
xcoords = [range(2,31)]
This line will create an array of length 1. The only element in that array is an array of the numbers 2 -> 30. Your loop is printing the elements of the outer array. Change that line to:
xcoords = range(2,31)
This answer is correct for Python 2 because the range function returns a list. Python 3 will return a range object (which can be iterated on producing the required values). The following line should work in Python 2 and 3:
xoords = list(range(2,31))
First of all, change xcoords so that it isn't a list inside a list:
xcoords = range(2, 31)
We don't need to iterate over a list using an index into the list using len(xcoords). In python we can simply iterate over a list like this:
for coord in xcoords:
print "i: ", coord
If we did need to keep track of the index we could use enumerate:
for i, coord in enumerate(xcoords):
print str(i) + ":", coord

How to find the maximum number in a list using a loop?

So I have this list and variables:
nums = [14, 8, 9, 16, 3, 11, 5]
big = nums[0]
spot = 0
I'm confused about how to actually do it. I want to use this exercise to give me a starter. How do I do that on Python?
Usually, you could just use
max(nums)
If you explicitly want to use a loop, try:
max_value = None
for n in nums:
if max_value is None or n > max_value: max_value = n
Here you go...
nums = [14, 8, 9, 16, 3, 11, 5]
big = max(nums)
spot = nums.index(big)
This would be the Pythonic way of achieving this. If you want to use a loop, then loop with the current max value and check if each element is larger, and if so, assign to the current max.
nums = [14, 8, 9, 16, 3, 11, 5]
big = None
spot = None
for i, v in enumerate(nums):
if big is None or v > big:
big = v
spot = i
Python already has built in function for this kind of requirement.
list = [3,8,2,9]
max_number = max(list)
print (max_number) # it will print 9 as big number
however if you find the max number with the classic vay you can use loops.
list = [3,8,2,9]
current_max_number = list[0]
for number in list:
if number>current_max_number:
current_max_number = number
print (current_max_number) #it will display 9 as big number
Why not simply using the built-in max() function:
>>> m = max(nums)
By the way, some answers to similar questions might be useful:
Pythonic way to find maximum value and its index in a list?
How to find all positions of the maximum value in a list?
To address your second question, you can use a for loop:
for i in range(len(list)):
# do whatever
You should note that range() can have 3 arguments: start, end, and step. Start is what number to start with (if not supplied, it is 0); start is inclusive.. End is where to end at (this has to be give); end is exclusive: if you do range(100), it will give you 0-99. Step is also optional, it means what interval to use. If step is not provided, it will be 1. For example:
>>> x = range(10, 100, 5) # start at 10, end at 101, and use an interval of 5
>>> x
[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95] # note that it does not hit 100
Since end is exclusive, to include 100, we could do:
>>> x = range(10, 101, 5) # start at 10, end at 101, and use an interval of 5
>>> x
[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100] # note that it does hit 100
For the Max in List Code HS I've managed to get most of the auto grader to work for me using this code:
list = [-3,-8,-2,0]
current_max_number = list[0]
for number in list:
if number>current_max_number:
current_max_number = number
print current_max_number
def max_int_in_list():
print "Here"
I'm not sure where the max_int_in_list goes though. It needs to have exactly 1 parameter.
To print the Index of the largest number in a list.
numbers = [1,2,3,4,5,6,9]
N = 0
for num in range(len(numbers)) :
if numbers[num] > N :
N = numbers[num]
print(numbers.index(N))
student_scores[1,2,3,4,5,6,7,8,9]
max=student_scores[0]
for n in range(0,len(student_scores)):
if student_scores[n]>=max:
max=student_scores[n]
print(max)
# using for loop to go through all items in the list and assign the biggest value to a variable, which was defined as max.
min=student_scores[0]
for n in range(0,len(student_scores)):
if student_scores[n]<=min:
min=student_scores[n]
print(min)
# using for loop to go through all items in the list and assign the smallest value to a variable, which was defined as min.
Note: the above code is to pick up the max and min by using for loop, which can be commonly used in other programming languages as well. However, the max() and min() functions are the easiest way to use in Python to get the same results.
I would add this as a reference too. You can use the sort and then print the last number.
nums = [14, 8, 9, 16, 3, 11, 5]
nums.sort()
print("Highest number is: ", nums[-1])
scores = [12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27,
28, 29, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 31, 31, 37,
56, 75, 23, 565]
# initialize highest to zero
highest = 0
for mark in scores:
if highest < mark:
highest = mark
print(mark)

Categories