Counting characters in a list - python

Write a function called count_numbers that takes in a list containing numbers and returns the count of numbers in the list. Your program has to cater to the possibility of having a list of numbers as element(s) in the input parameter. You can assume that the input parameter is at the most a 2-dimensional list.
Here is the output when file is run calling the function as:
>>> print("Count of numbers", count_numbers([4,6,[1,2],10,[-1,-3]]))
Count of numbers:7
My answer i got was 5 instead of 7.
here is my working:
def count_numbers(numbers):
result = []
for element in numbers:
for subelement in [element]:
result += [subelement]
results = len(result)
return results

If you want to do this manually, you are going to need to test the type of each element, to check if you are dealing with an int or a list, if a list you will have to create a deeper loop. After you count the element you will need to append it to a list, to check against so you don't count that same element again.
lst = [4,6,[1,2],10,[-1,-3]]
count = 0
seen = []
for i in lst:
if isinstance(i, list):
for j in i:
if j not in seen:
count += 1
seen.append(j)
else:
pass
else:
if i not in seen:
count += 1
seen.append(i)
else:
pass
print(count)
You can flatten your list and use collections.Counter as well
from collections import Counter
lst = [4,6,[1,2],10,[-1,-3]]
new_lst = []
for i in lst:
if isinstance(i, list):
new_lst.extend(i)
else:
new_lst.append(i)
c = Counter(new_lst)
print(c) # Counter({4: 1, 6: 1, 1: 1, 2: 1, 10: 1, -1: 1, -3: 1})
print(sum(c.values())) # 7

not quite sure what you what to do, but i guess this should work:
for elem in line:
if type(elem) == int:
result += 1
elif type(elem) == list:
for sub in elem:
if type(sub) == int:
result += 1
bear in mind that this code is realy ugly ;) but it should help get you started

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 create a new list from a previous list where elements are added to their position if the position is even?

Define a function named addPosToElem(...) which receives a list with integer numbers and returns a new list containing the elements form the original list in even positions where the position is added to the element. The list can possibly be empty
As an example, the following code fragment:
lst = [0,10,20,30,40,50]
print(addPosToElem(lst))
gives the output:
[0, 22, 44]
My code:
def addPosToElem(lst):
for i in range(lst[0], len(lst)):
if (lst[i] % 2) == 1:
element_odd = int(lst[i])
elif (lst[i] % 2) == 0:
element_even = int(lst[i]) + lst.index(i)
new_lst = element_odd + element_even
return new_lst
I keep getting 1 is not in list, how to fix my code?
The most pythonic way to do this is with list comprehension:
[num + place for place, num in enumerate(lst) if place % 2 == 0]
# [0, 22, 44]
Or with regular loop:
new_lst = []
for place in range(len(lst)):
if place % 2 == 0:
new_lst.append(lst[place] + place)
new_lst # [0, 22, 44]
This will do what you want. It isn't as 'good' as list comprehension but may be slightly more readable for a beginner.
def addPosToElem(lst):
new_lst = []
for i in range(len(lst)):
if (i % 2) == 0:
new_lst.append(lst[i] + i)
return new_lst
There are a few error with this approach:
As mentioned in the comment, you are checking lst[i]%2, you should check i%2 to get the indices.
You are checking lst.index(i) which fails in the 2nd iteration, because i is 1 and 1 is not in list.
You are not using the element_odd and element_odd as lists, so even if somehow your algorithm worked you would get two values as output.
Instead try this:
def addPosToElem(lst):
return [index+value for index, value in enumerate(lst) if index%2 == 0]
Your fixed code will be:
def addPosToElem(lst):
new_lst = []
for i in range(lst[0], len(lst)):
if (i % 2) == 0:
element_even = int(lst[i]) + i
new_lst.append(element_even)
return new_lst

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

Insertion sort doesn't sort

I have attempted to create an insertion sort in python, however the list returned is not sorted. What is the problem with my code?
Argument given: [3, 2, 1, 4, 5, 8, 7, 9, 6]
Result: 2
1
3
6
4
7
5
8
9
Python code:
def insertion_sort(mylist):
sorted_list = []
for i in mylist:
posfound = 0 #defaults to 0
for j in range(len(sorted_list)):
if sorted_list[j] > i:
sorted_list.insert(j-1, i) #put the number in before element 'j'
posfound = 1 #if you found the correct position in the list set to 1
break
if posfound == 0: #if you can't find a place in the list
sorted_list.insert(len(sorted_list), i) #put number at the end of the list
return sorted_list
You need to change sorted_list.insert(j-1, i) to be sorted_list.insert(j, i) to insert before position j.
insert(j-1, ..) will insert before the previous element, and in the case where j=0 it'll wrap around and insert before the last element.
The Python data structures tutorial may be useful.
As Efferalgan & tzaman have mentioned your core problem is due to an off-by-one error. To catch these sorts of errors it's useful to print i, j and sorted_list on each loop iteration to make sure they contain what you think they contain.
Here are a few versions of your algorithm. First, a repaired version of your code that fixes the off-by-one error; it also implements Efferalgan's suggestion of using .append if an insertion position isn't found.
def insertion_sort(mylist):
sorted_list = []
for i in mylist:
posfound = 0 #defaults to 0
for j in range(len(sorted_list)):
if sorted_list[j] > i:
sorted_list.insert(j, i) #put the number in before element 'j'
posfound = 1 #if you found the correct position in the list set to 1
break
if posfound == 0: #if you can't find a place in the list
sorted_list.append(i) #put number at the end of the list
return sorted_list
Here's a slightly improved version that uses an else clause on the loop instead of the posfound flag; it also uses slice assignment to do the insertion.
def insertion_sort(mylist):
sorted_list = []
for i in mylist:
for j in range(len(sorted_list)):
if sorted_list[j] > i:
sorted_list[j:j] = [i]
break
else: #if you can't find a place in the list
sorted_list.append(i) #put number at the end of the list
return sorted_list
Finally, a version that uses enumerate to get the indices and items in sorted_list rather than a simple range loop.
def insertion_sort(mylist):
sorted_list = []
for u in mylist:
for j, v in enumerate(sorted_list):
if v > u:
sorted_list[j:j] = [u]
break
else: #if you can't find a place in the list
sorted_list.append(u) #put number at the end of the list
return sorted_list
As often, it was a off-by-one error, the code below is fixed. I also made some parts a bit prettier.
def insertion_sort(mylist):
sorted_list = []
for i in mylist:
for index, j in enumerate(sorted_list):
if j > i:
sorted_list.insert(index, i) #put the number in before element 'j'
break
else:
sorted_list.append(i) #put number at the end of the list
return sorted_list

Counting evens in a two-dimensional list?

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.

Categories

Resources