Python insert number in list sequence - python

I am trying to insert a number into a list of a sequence of numbers, for some reason this small program just sits there consuming CPU power... no idea why it's not working:
number = 5
lst = [4,5,6]
if all(x > number for x in lst):
lst.insert(0,number)
elif all(x < number for x in lst):
lst.append(number)
else:
for i,v in enumerate(lst):
if v>number:
lst.insert(i-1,number)
print (lst)
expected output:
lst = [4,5,5,6]

Your for loop is inserting the number 5 into the middle of the list a theoretically infinite amount of times (or until you run out of whatever limited resource the list consumes, whichever happens first).
1) for i,v in enumerate(lst):
2) if v>number:
3) lst.insert(i-1,number)
On the first pass, line 1 starts the loop with v = 4 and i = 0. Line 2 finds v is not greater than number.
On the second pass, line 1 continues the loop with v = 5 and i = 1. Line 2 is also false.
Third pass, line 1: v = 6, i = 2. Line 2 finds a true statement and moves to line 3. Line 3 inserts the object referenced by number into position i - 1, inserting 5 into position 1 of the list.
At this point the list is:
lst = [4, *5*, **5**, 6]
The italicized 5 is the number you added to the list. The bolded 5 is where the current pointer is, i = 2. Notice that the 6 we just checked got moved forward with the insert.
Fourth pass: v = 6, i = 3. Line 2 finds a true statement and moves to line 3. Line 3 inserts the object referenced by number into position i - 1, inserting 5 into position 2 of the list.
At this point the list is:
lst = [4, 5, *5*, **5**, 6]
etc etc etc.
A quick fix:
for i, v in enumerate(lst):
if v > number:
lst.insert(i-1, number)
**break**
You're just checking for and adding a single number, so break out of the loop once you insert it, since you're done.

Related

How to iterate over indices instead of elements?

I need to make a function that takes a given array and searches it for the first occurence of a sequence of at least two numbers. The sequence starts with a higher number, then drops to a lower one then growing, something like this: 6 6 3 3 4 5 5 6.
Next I have to put it into a different array, printing it out afterwards.
I tried doing this:
for e in sub_array:
length = 0
while e > e+1 or e+1 <= e+2:
res.append(e)
length += 1
e += 1
if length >= 2:
return res
else:
res = []
return res
, but it uses [e] as an element instead of an index, returning nothing (putting e in square brackets does not solve the problem).
For example, if I put in something like [2, 9, 6, 2, 5, 7, 7, 3], it must return [6, 2, 5, 7, 7], but the function returns an empty array []
Any tips on how I can make this work?
Edit: I am not tied to using indices, I'm searching for any way to make this work. I'm just trying to figure out how to solve this problem in the most efficient way.
This solves your problem as you have stated it. The loop can be in several states: searching for a pair that goes down, gathering, and finding a pair that goes down while gathering.
def find_sequence(array):
last = None
found = []
for e in array:
# If this is the first element, save it for next time.
if last is None:
last = e
elif not found:
# If we have not found a sequence and numbers are increasing,
# just save and check for next time.
if e >= last:
last = e
# Otherwise, we have the start of a new potential sequence.
else:
found = [last, e]
# If we are in the middle of gathering a sequence and a number
# goes down, that's the end of the sequence.
elif e < found[-1]:
break
# Otherwise, add the number to the sequence.
else:
found.append(e)
return found
array = [2,4,6,2,5,7,7,3]
print(find_sequence(array))
print(find_sequence([6,7,7,3,4,5,6,6,7,2]))

Count the unique elements in a list without set

I am currently attempting to make a program that will count and print the number of unique elements in a list.
My code:
def solution(N, A):
yee = 1
for i in range(1, len(A)):
j = 0
for j in range(i):
if(A[i] == A[j]):
yee-=1
if(i==j+1):
yee +=1
print(yee)
N = int(input())
A = []
n = 0
for e in input().split():
if(n<N):
A.append(int(e))
n+=1
solution(N, A)
With the list containing (1 2 3 1 4 2 5 6 7 8) the output is supposed to be 6. However, my program is returning 8. I believe this is due to the program counting the 1 and 2, even though they are not technically unique in the problem. I'm sure it's and easy fix, but I just can't seem to figure it out. Any help would be greatly appreciated!!
The only way you would get the output of 6 for (1, 2, 3, 1, 4, 2, 5, 6, 7, 8) would be if you wanted to count the number of elements that appear exactly once, as opposed to the number of unique elements (there are 8 elements, of which two are repeated more than once).
You could do this in a one-liner:
def num_single_elements(A):
return len(list(e for e in A if A.count(e) == 1))
Similarly if you need to keep check of the number of elements further on in your code, I like dictionary comprehension for this kind of problem:
dict_A = {x:A.count(x) for x in A}
print(len([x for x in dict_A if dict_A[x] == 1]))
As Green Cloak Guy said, you seem to be looking for the number of elements which appear exactly once, and his answer contains a solution to that. Here's a simple solution for finding the number of unique elements:
def unique_elements(A):
return len([ 1 for (index, a) in enumerate(A) if A.index(a) == index ])
The idea here is to count up the first occurrence of each unique value.
enumerate allows us to get the index of the item, as well as the item itself, as we iterate;
A.index(a) gives the index of the first time the value of a appears in A.
So, if we count up all the times index equals A.index(a), we're counting the first time an item appears which has never appeared before, which is equal to the number of unique elements.

Add a 0 after each even number in list [closed]

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 5 years ago.
Improve this question
I am trying to add a 0 after each even number, every time i run the code it infinitely prints the value of i, which is 0 every time.
I've tried this so far:
def linear_list (n):
x = []
for y in range (1, n+1):
x.append (y)
return x
n = int (input ("Enter the lenght of the list: "))
alist = linear_list (n)
for i in alist:
print (i)
if i % 2 == 0:
alist.append(0)
print (alist)
But for i >= 2my code is printing infinite zeroes:
Enter the lenght of the list: 5
0
0
0
0
...
Expected output:
[1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0, 9, 10, 0]
How can achieve the correct list?
Make it work, make it right, make it fast
Here the make it work part.
You are modifying the list and iterating it at the same time.
Try:
otherlist = []
for i in alist:
print (i)
otherlist.append(i)
if i % 2 == 0:
otherlist.append(0)
print (otherlist)
You're increasing the alist length every time you append to it, and since you're looping through it you will never exit the loop - the list never ends. You don't want to change the list, but the value within it, so enumerate it:
for i, v in enumerate(alist):
print (v)
if v % 2 == 0:
alist[i] = v * 10 # assuming it's a number, use v + "0" if its a string
The iterator create by the for loop is a separate object from the list you iterate over. Your for loop is similar to a while loop like
itr = iter(a)
while True:
try:
i = next(itr)
except StopIteration:
break
if i % 2 == 0:
a.append(0)
a.append always adds a 0 to the end of the list, without affecting the current position of the iterator. Since 0 is even, once the iterator reaches the what was the end of the list when you started the loop, it sees a 0, and so another 0 gets added to the end of the list. It continues reading the next 0 and adding another 0, on and on, forever.
Technically, you can do what you want, but it's rather tricky and very easy to get wrong. (It took me about 8 tries to get this example right.) The trick is to create a separate iterator explicitly, one that you can access in the body of the loop, rather than letting the for loop generate the iterator for you. This allows you to insert a 0 after the current value in the list, then skip over the new 0 so that you won't see it on the next iteration of the loop.
Don't actually do this if you can avoid it: it is far simpler to create a new list that replaces the old list after the loop.
That said, on with the show:
a = range(10)
itr = enumerate(a) # A list of index, value pairs
for index, value in itr:
if value % 2 == 0:
i = index + 1
a[i:i] = [0] # Put a 0 after the current position
next(itr) # Skip over the 0 you just added
assert a == [0, 0, 1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0, 9]
You can shorten this a bit by starting the index at 1 instead of 0, effectively pre-adding 1 to each index before you need it.
a = range(10)
itr = enumerate(a, start=1)
for i, value in itr:
if value % 2 == 0:
a[i:i] = [0]
next(itr)

Get the pairs of values from a list according to a condition without elements repeating

I have a list of integers like:
1 3 4 4 9 7 10 (the number of elements is between 1 and 200000)
and an integer variable D, it lies between 0 and 10^9.
Let it be 5 for example.
I need to count how many pairs in the list have a difference between each other not bigger than a variable D but the tricky part is that if I took the zero element with value 1 and the first element with the value 3(the difference between them meets the condition) I can't use these elements of a list again.
For example for the sequence above the answer is 3 pairs: (1,3) (4,4) (7,9)
I wrote a code which seems to be correct but I need a hint how to change the input sequence and the variable d the way it will output wrong answer
list_of_colors = [1, 3, 4, 4, 9, 7, 10]
d = 5
number_of_pairs = 0
list_of_colors.sort() # the values in the list are not always sorted
i = 0
while True:
if i >= len(list_of_colors):
break
if i != len(list_of_colors) - 1:
# if the number i in list and i+1 is the same or difference between them not greater than a variable d...
if (int(list_of_colors[i]) == int(list_of_colors[i + 1])) or abs(int(list_of_colors[i]) - int(list_of_colors[i + 1])) <= d:
#print list_of_colors[i]," ",list_of_colors[i + 1]
number_of_pairs += 1 # increasing the number of the acceptable pairs
i += 2 # jump over two elements, we already counted them
continue
i += 1
print number_of_pairs
I need another algorithm to compare it with the results of my algorithm on the various range of the input sequence and the variable d
Suggest your ideas please
I have a greedy solution for this problem:
Sort the input sequence.
Parse the sorted sequence as follows:
For ith element in the sequence,
if |a[i+1]-a[i]| <= D,
then pair up the elements. Proceed to process i+2th element.
else
proceed to process i+1th element.
My solution here is to first "clean" the list what means I made the number of elements even. Then I've converted the list into a list of tuples (pairs).
My result for this example is 3 pairs in order to your condition.
list_of_colors = [1, 3, 4, 4, 9, 7, 10]
d = 5
number_of_pairs = 0
list_of_colors.sort() # the values in the list are not always sorted
# remove the last element if the number of elements is odd
if len(list_of_colors) % 2 != 0:
list_of_colors = list_of_colors[:-1]
# create a list of tuples
list_of_colors = [tuple(list_of_colors[i:i+2]) for i in range(0, len(list_of_colors), 2)]
for i in list_of_colors:
if (int(i[0]) == int(i[1])) or abs(int(i[0])) - int(i[1]) <= d:
number_of_pairs += 1
print number_of_pairs

multiplying in a list python

I am doing some homework and I am stuck. I supposed to write a code in Python 3, that reads a text file that is like a bill with an amount of numbers. I am supposed to write the code so it will calculate the total amount.
I figured that a bill(simple example) will contain a number and the a prise. like:
2 10$
1 10 $
and so on
So I figured that I create a list with all numbers in it and then I want to multiply the first with the second element in the list and then jump in the list so the tird and the fourth element get multiply and so on, until there is no more numbers in my list. During this happens I want the sums of every multiplication in a new list called sums there they later will be summed.
my code looks like this so far:
file = open('bill.txt')
s = file.read()
file.close()
numbers = []
garbage = []
for x in s.split():
try:
numbers.append(float(x))
except ValueEror:
garbage.append()
print(numbers)
for n in numbers:
sums = []
start = 0
nxt = start + 1
t = numbers[start]*numbers[nxt]
if n <= len(numbers):
start += 2
nxt += 2
summor.append(t)
if n == len(numbers):
print(sum(sums))
The problem in your code is likely that you keep resetting sums for every number in the list. So you basically keep forgetting the sums you previously collected. The same applies to start and nxt. If you move these definition outside of the loop, and also fix the summor.append(t) to sums.append(t) it should almost work. Also note that the loop variable n does not iterate over indexes of numbers but over the actual items (i.e. the numbers). So the check at the end n == len(numbers) is unlikely to do what you expect. Instead, you can just put the print after the loop because you know that when you reached that point the loop is over and all numbers have been looked at.
A common idiom is to use zip to combine two elements with each other. Usually, you use zip on two different iterators or sequences, but you can also use zip on the same iterator for a single list:
>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> it = iter(numbers)
>>> for a, b in zip(it, it):
print(a, b)
1 2
3 4
5 6
7 8
As you can see, this will group the numbers automatically while iterating through the list. So now you just need to collect those sums:
>>> sums = []
>>> it = iter(numbers)
>>> for a, b in zip(it, it):
sums.append(a * b)
>>> sum(sums)
100
And finally, you can shorten that a bit more using generator expressions:
>>> it = iter(numbers)
>>> sum(a * b for a, b in zip(it, it))
100
This may be a typo when you entered it but on your 2nd line of data there is a space between the amount and $ and no space on the line above. This will cause some problems when striping out the $.
Try this:
total = 0
with open('data.txt', 'r') as f:
lines = f.readlines()
amounts = []
garbage = []
for line in lines:
try:
multiples = line.split()
multiplier = multiples[0]
amount = multiples[1].strip('$\n')
amounts.append(int(multiplier)*float(amount))
except:
garbage.append(line)
total = sum(amounts)
print(total)
With some minor formatting on output or the text data you should be able to get the result you want. Here is the txt data I used:
2 10$
1 10$
3 20.00$
and the output is:
90.0
Also, you may want to get away from file = open('data.txt', 'r') which requires you to explicitly close your file. Use with open('data.txt', 'r') as f: and your file will implicitly be closed.
Firstly, I would say, quite a good attempt. If you don't want to be spoiled, you should not read the code I have written unless you try out the corrections/improvements yourself. (I am not a pro)
Well, like you said every line contains 2 numbers that need be multiplied, you should start by reading line by line & not individual numbers as that might get troublesome.
file = open('bill.txt')
s = file.readlines()
file.close()
numbers = []
garbage = []
for line in s:
try:
line.strip('$') # removes the trailing $ sign for easy number extraction
numbers.append(map(int, line.split()))
except ValueEror:
garbage.append(line)
print(numbers)
Later, when summing up the multiplication of the number & the bills, you probably won't require a list for that, instead a sum integer variable should be enough.
sum = 0
for num, bill in numbers:
sum += num * bill
print("The total amount is", sum)
Several things:
sums = [] is inside the loop for n in numbers. This means you're resetting the sums list every time. You should move this outside the loop.
The same applies to start = 0 and nxt = start + 1. These values now keep being reset to 0 and 1 respectively for each number in the list.
You are comparing if n <= len(numbers): but what is n? It's an actual value in your list of numbers, it doesn't represent the position in the list. You should replace this with while start < len(numbers): - as long as the starting position is still within the list we should keep going. This also means you can remove n from your code.
The code now becomes:
sums = []
start = 0
nxt = start + 1
while start < len(numbers):
t = numbers[start]*numbers[nxt]
start += 2
nxt += 2
sums.append(t)
print(sum(sums))

Categories

Resources