Counting evens in a two-dimensional list? - python

Hey guys I'm trying to make a program that counts the evens in a two-dimensional list. The program I made so far is not returning what I want it to.
def Evens(x):
count = 0
x = len(x)
for a in range(x):
if a%2 == 0:
count = count + 1
return count
that keeps returning 2 for the list Evens([[1,3],[1,9,7,1,3],[13]]) when I want it to return 4. I tried everything but it seems to not be working correctly.
Thanks

The problem you're encountering is that you are checking the indices to see if they are even, not the values. You're also not checking in the sublists.
More straightforward, IMO, is to do this:
import itertools
def evens(x):
return sum(a % 2 == 0 for a in itertools.chain.from_iterable(x))

You need to actually iterate over the sublists.
def evens(l):
count = 0
for l2 in l:
for i in l2:
if i%2 == 0:
count += 1
return count
Or you can you can take a much simpler approach.
def evens(l):
return sum(i%2==0 for l2 in l for i in l2)
The second approach uses the fact that in an integer context, True == 1 and False == 0, so you would get the expected result.

You need to iterate over all the sublists:
In [34]: l = [[1,4,3],[12,0,7,10,3],[13]]
In [35]: sum(n%2 == 0 for sub in l for n in sub)
Out[35]: 4

You need to iterate over the elements in each sublist as well:
def count_evens(l):
total = 0
for l2 in l:
for item in l2:
if item % 2 == 0:
total += 1
return total
What you were doing before was iterating over the number of sublists (i.e. [0, 1, 2, 3] for a list with 4 elements). Your code was working, but it wasn't working properly.

Related

Sum of lowest numbers that are part of an arithmetic sequence

I would like to iterate through a list of integers, calculate the sum of the lowest numbers that belongs to an arithmetic sequence with common difference 1 + the numbers that are not part of a sequence:
mylist = [2,3,4,10,12,13]
So, from mylist it would be 2 (from 2,3,4) + 10 (not part of a sequence) + 12 (from 12,13)
I've managed to make something work, but I could only figure out how to do it, if the list is reversed. And I am sure there is a better/cleaner solution that mine:
mylist = [13,12,10,4,3,2]
result = mylist[-1] #if I don't do this, I don't know how to grab the last item in the list
for i in range(len(mylist)-1):
if mylist[i] - mylist[i+1] == 1:
continue
else:
result += mylist[i]
Hope someone will help me out, and that I get a little wiser in my coding journey. Thanks.
#KennethRasch - earlier post would work. Alternatively, you can do this as well:
Try to find each possible subsequence's starting numbers as starts then just sum them to get answer.
L = [13,12,10,4,3,2]
L.sort()
starts = [x for x in L if x-1 not in L]
print(starts)
result = sum(starts)
print(result) # 24
Alternatively, you can put this into a function for future re-use it:
def sum_lowests(L):
'''L is a numbers sequence '''
L.sort()
starts = [x for x in L if x-1 not in L]
#ans = sum(starts) # can skip this step; just to make it clear
return sum(starts)
if __name__ == '__main__':
L = [13,12,10,4,3,2]
A = [1, 2, 3, 5,6, 9,10,11, 16]
print(sum_lowests(L))
print(sum_lowests(A)) # 31
Keep a running sum, a running index, and iterate while it's still a sequence:
mylist = [13,12,10,4,3,2]
mylist.sort() # this way sequences will be contiguous in the list
cur_index = 0
cur_sum = 0
while cur_index < len(mylist):
# add the current element to the sum
cur_sum += mylist[cur_index]
# now iterate through while it's a contiguous sequence
cur_index += 1
while cur_index < len(mylist) and mylist[cur_index] == mylist[cur_index - 1] + 1:
cur_index += 1
print(cur_sum)

How to compare one object in a list to every other object in that list

So, for example, say I have a list like
List1 = [5, 6, 7, 1, 40]
And I want the solution to return true only if the value in the list that we’re looking at is 5 times large than every other member of the list. So if we’re looking at the first item, 5, the solution should return false (even though it is 5 times bigger than 1 it is not compared to the other members) and should return true when looking at the last member, 40. In python I wrote something like:
for i in range(len(list1)):
for j in range(i + 1, len(list1)):
if i >= (j*5):
return True
else:
return False
But I don’t think this is a great solution. I know this shouldn’t be so hard but I’m going through some health issues that’s making this hard for me. Any thoughts or help would be appreciated!
You are comparing i and j instead of comparing the list values and you are returning true before comparing your list1[i] value with all other list1[j] values.
Check the condition for all the j values, and use count to check if the value is greater than all other values.
count = 0
for i in range(len(list1)):
for j in range(i + 1, len(list1)):
if (list1[i] >= (list1[j]*5)):
count = count + 1
if(count == len(list1) - 1):
return True
return False
Try this:
def check(lst, value_index):
return lst[value_index] >= 5 * max(q for e, q in enumerate(lst) if e != value_index)
The following will give you a list of True/False value for each element of List1 where your condition is satisfied.
[all(List1[i] > List1[j] * 5 for j in range(len(List1)) if i != j)
for i in range(len(List1))]

Using sum() to print the sum of even numbers in a list

I am having trouble finding information on using sum to take from a list. I know how to use sum with range, for example:
sum = 0
for i in range(50):
sum=sum + i
print (sum)
But I can't get my code to work when I am using a list such as [1, 2, 6, 7, 8, 10] and taking the even numbers using sum. Can anyone point me in the right direction?
You can filter out odd-values:
def is_even(x):
# if the remainder (modulo) is 0 then it's evenly divisible by 2 => even
return x % 2 == 0
def sum_of_evens(it):
return sum(filter(is_even, it))
>>> sum_of_evens([1,2,3,4,5])
6
Or if you prefer a conditional generator expression:
>>> lst = [1,2,3,4,5]
>>> sum(item for item in lst if item % 2 == 0)
6
Or the explicit (long) approach:
lst = [1,2,3,4,5]
sum_ = 0
for item in lst:
if item % 2 == 0:
sum_ += item
print(sum_) # 6

Python: check if a list can be sorted by swapping two elements, only one swap is allowed

Here in below code, I'm trying to find out if there are two elements in left side which are greater than right side element but this doesn't seem to work for my problem. Any hints to write further logic? I'm stuck here.
swap.py
def swap(lst):
count = 0
for k in range(0, len(lst)-1):
if lst[k] > lst[k+1]:
count += 1
if int(count) == 2:
print "Swapped"
elif int(count) == 0:
print True
else:
print False
if __name__ == "__main__":
swap([1,2,3,4,0])
swap([6,4,2,5])
swap([6,4,2,8])
swap([1,4,5])
My expected output from program -
[1,4,5] will return True
[6,4,2,8] will return Swapped
[6,4,2,5] will return False
from itertools import combinations
def is_swappable(lst):
s = sorted(lst)
for i, j in combinations(range(len(lst)), 2):
l = lst[:]
l[i], l[j] = l[j], l[i]
if l == s:
return True
return False
Here's a pretty naive solution. Tries swapping every pair in the list and sees if that results in the sorted list.
I did not understand the "swapped" condition but the following code snipped will tell you if you can sort an array in one swap or not.
Code is written in Python 3 and the complexity of this code is O(nlog(n))
def checkOneSwap(arr):
N = len(arr)
if N <= 2:
print(True)
arr2 = []
for index in range(N):
arr2.append(arr[index])
arr2.sort()
counter = 0
for i in range(N):
if arr[i] != arr2[i]:
counter += 1
if counter == 0 or counter == 2:
print(True)
else:
print(False)
checkOneSwap([1,2,3,4,0]) # False you definetly need for than 2 swap to make this array sorted
checkOneSwap([6,4,2,5]) # False [2,4,5,6] -> swap(6,2) and then swap(6,5) require 2 swap to make this array sorted
checkOneSwap([6,4,2,8]) # True [2,4,6,8] -> swap(6,2), one swap required to make this array sorted
checkOneSwap([1,4,5]) # True [1,4,5] -> already sorted,counter = 0
Can be done with for loop, but I prefer list comprehension. Zip sorted and unsorted list and create a list of mismatches. If the length of mismatches is more than 2, then you can't sort in 1 swap.
def is_sortable_by_one_swap(unsorted_list):
mismatches = [x for x in zip(unsorted_list, sorted(unsorted_list)) if x[0] != x[1]]
return len(mismatches) <= 2

Check if a number is found x amount of times consecutively in a 2d list

I want to know if a number in a list is found j times consecutively ,this is my list :
list=[[1, 1, 1,1],
[0, 0, 0,0],
[2, 2, 2,2]
[2, 2, 2,2]]
And this is what i wrote :
def alignment(list,n,j):
for y in range (n):
for x in range (n-j):
counter = 0
for z in range(j):
if list[y][x]== list[y][x+z]:
counter+=1
if counter == j :
return True
But this function will check if any number is found consecutively,i want to add another parameter to this function so i can specify what number i want to look for in the list .
n means there are n rows and columns and j is how many times is how many times the number needs to be found .
Your requirements are unclear. However, this would be a slightly modified version of your code which would yield what I believe you're seeking.
target is the number for which you want to know if there are j consecutive entries.
def alignment(list,n,j,target):
for y in range (n):
for x in range (n-j):
counter = 0
if list[y][x] == target:
for z in range(j):
if list[y][x]== list[y][x+z]:
counter+=1
if counter == j :
return True
def alignment(nums,j,target):
for row in nums: # get each row
counter = 0
for i in row: # get each number
if i != target: # check if some other number was gotten
if counter == j:
return True
counter = 0 # reset counter
continue
counter += 1
if counter == j:
return True
return False
No need for the n argument.
There are a few problems with your code:
the n parameter is not needed, you can get the size of the list by using len(list)
you should not use list as a variable name, as it shadows the builtin list function
with for x in range (n-j) you are assuming that each sublist has the same number of elements as the parent list
your function also returns True if the number appears more than j times in a row
you are doing lots of double work by using three loops instead of just two
You can fix this, and also add the parameter for the number to be repeated, as shown in the other answers. However, using just loops and conditions, the resulting code will be very unwieldy.
Instead, you can create a function as you describe using any and itertools.groupby. groupby groups equal numbers, then you just have the check the len of those groups and see if any is long enough, and whether it's the correct number, for any of the sublists.
def alignment(lst, num, count):
return any(any(n == num and len(list(g)) == count
for n, g in itertools.groupby(l))
for l in lst)
This will return True if num appears exactly count times consecutively in any of the sublists.

Categories

Resources