Why is my code not following the command? - python

def pairs(x):
for num in x:
if num == num :
return x
y = [2, 2, 2, 2, 2, 4, 3, 3]
pairs (y)
print (y)
this is returning [2, 2, 2, 2, 2, 4, 3, 3]
but I want to return [2,2,3]
I've tried 3 codes already other than this one
help me

Your code seems to be intended to find all the numbers that exist in pairs in the list. The best way would be (for a sorted list) to just cycle through the list and check successive elements.
Your code just matches if the current number is the same as the current numbers always returns true and returns all elements. A correct Code might be:
y = [2, 2, 2, 2, 2, 4, 3, 3]
y=sorted(y) # Sorts the given list
def pairs(arr):
i = 0 # Counter variable
res = [] #result list
while i < len(arr)-1:
if arr[i] == arr[i+1]:
res.append(arr[i]) # If the successive elements are the same, add
# it to the result array and since we have already
# checked the next element, increment the counter by
# two
i+=2
else:
i+=1 # If the elements are different we need to check the
# next element as well so increment by 1
return res
print(pairs(y))

You are comparing the element with itself which is always true. Here is the correct logic
y = [2, 2, 2, 2, 2, 4, 3, 3]
filt = []
i=0
while (i< (len(y)-1)):
if y[i] == y[i+1]:
filt.append(y[i])
i+=1
i+=1
print(filt)

Related

How to reverse list without in-built function [duplicate]

This question already has answers here:
How can I reverse a section of a list using a loop in Python?
(5 answers)
Closed 3 years ago.
I have this problem for homework and I have almost gotten it but not quite. I have to develop some code that takes a list and a number as parameters. The function returns a copy of the list with the first number of items reversed. I can not use in-built functions, slicing or reverse, I can only use append.() and range(). Would really appreciate someone's help with fixing my current code and maybe explaining how you fixed it? Thankyou!!!
str_list6 = ['e', 'd', 'u', 'd']
def length(my_list):
total = 0
for c in my_list:
total += 1
return total
def remove_value(my_list):
res = []
for i in range(length(my_list) -1, -1, -1):
res.append((my_list)[i])
return res
the example given:
numList = [1, 2, 3, 4, 5, 6, 7]
number = 4
The call to reverse(numList, number) should
return the new list
[4, 3, 2, 1, 5, 6, 7].
So my code currently simply reverses the list however (its hard to explain), it needs to reverse with the shift of the 'number'. Hopefully this make sense!
The problem here is that you are not taking into account the number to shift. In your example you are given two variables, the list and the number to shift (is this the position or the actual number you are looking for? - assuming position), yet your code only takes the list.
def remove_value(my_list, pos_to_reverse):
res = []
for i in range(pos_to_reverse-1, -1):
res.append(my_list[i])
for i in range(pos_to_reverse, length(my_list)-1):
res.append(my_list[i])
return res
You were getting close! I think the function below does what you want.
def reverse(numList,number):
# Make an empty list
reversedlist=[]
for i in range(number):
# i goes from 0 to number-1
reversedlist.append(numList[number-i-1])
# build a reversed list by adding each element
# of numList going in reverse order.
for i in range(number):
# i goes from 0 to number-1
numList[i]=reversedlist[i]
# change the first 'number' elements of the
# original list with the reversed list.
return numList
numList = [1, 2, 3, 4, 5, 6, 7]
number = 4
print(reverse(numList,number))
# prints: [4, 3, 2, 1, 5, 6, 7]
You can probably do like this.
l = [1, 2, 3, 4, 5, 6, 7]
n = 4
def solution(lst,n):
size = n
hiindex = size - 1
its = size//2
for i in range(0, its):
temp = lst[hiindex]
lst[hiindex] = lst[i]
lst[i] = temp
hiindex -= 1
return lst
print(solution(l,n))
You can use this tiny loop:
numList = [1, 2, 3, 4, 5, 6, 7]
number = 4
def reverse(l, n):
for i in range((n + 1) // 2):
l[i], l[n - i - 1] = l[n - i - 1], l[i]
return l
print(reverse(numList, number))
Output:
[4, 3, 2, 1, 5, 6, 7]

How do I stop the function when I have a unique list?

I tried a function that would remove both adjacent duplicates in a list. The remove any new duplicate pair and the function will keep going until there are no more duplicate pairs in the list.
I ran into the issue of figuring out how to tell the function to stop once I have a list without adjacent duplicates.
def removepair(no):
i = 1
if len(no) == 0 or len(no) == 1:
return no
while i < len(no):
if no[i] == no[i-1]:
no.pop(i)
no.pop(i-1)
i -= 1
i += 1
return removepair(no)
So far the function will return 0 or single elements after removal:
input: [1, 2, 2, 1] output: []
or
input: [4, 4, 4, 4, 4] output: [4]
But the problem is I don't know how to stop the recursive function once it has a list with more than 1 element:
input: [1,2,3,3,2,1,5,6,7]
expected output: [5,6,7]
We may be able to avoid boolean flags and counters if we set up our recursion carefully:
def removepairs(numbers):
if not numbers: # base case #1, empty
return numbers
first, *second_on = numbers
if not second_on: # base case #2, one element
return numbers
second, *third_on = second_on
if first == second:
return removepairs(third_on)
result = [first] + removepairs(second_on)
if result == numbers:
return numbers # base case #3, no change!
return removepairs(result)
print(removepairs([1, 2, 3, 3, 2, 1, 5, 6, 7]))
OUTPUT
> python3 test.py
[5, 6, 7]
>
If recursive function is not a requirement, it can be simply done using the following code. I have commented the print statement.
def removepair(input_list):
unique_input_list = list(set(input_list))
output_list = list(x for x in unique_input_list if input_list.count(x)%2 == 1)
#print('Input List: ', input_list)
#print('Output list: ', output_list)
return output_list
Input List: [1, 2, 3, 3, 2, 1, 5, 6, 7]
Output list: [5, 6, 7]
Input List: [4, 4, 4, 4, 4]
Output list: [4]
Input List: [1, 2, 3, 3, 2, 1]
Output list: []
Your recursion should stop when no elements where popped from the list, not when the list is almost empty:
def removepair(no):
L = len(no)
if L <= 1:
return no
i = 1
while i < len(no):
if no[i] == no[i-1]:
no.pop(i)
no.pop(i-1)
i -= 1
i += 1
if len(no) < L:
# elements where popped since the list len has decreased
return removepair(no)
else:
return no
Your code is difficult to understand since it uses a mix of recursion and side effects. Usually, you use either one or the other. Here you can replace your recursive call with a while:
def removepair(no):
while True:
L = len(no)
if L <= 1:
return no
i = 1
while i < len(no):
if no[i] == no[i-1]:
no.pop(i)
no.pop(i-1)
i -= 1
i += 1
if len(no) == L: # no elements where popped
return no
But it's not really Pythonic and I think you should not modify the parameter no inside the function but rather return a new list. Why not iterate over the list and do not copy the duplicates in the result?
def removepair(no):
ret = []
for e in no:
if ret and e == ret[-1]: # current element is the same as the last element
ret.pop()
else:
ret.append(e)
return ret
Or with a fold:
def removepair(no):
import functools
return functools.reduce(lambda acc, x: acc[:-1] if acc and acc[-1]==x else acc+[x], no, [])

Python List control flow - why won't skip elements already in list

Essentially trying to add numbers to list L based on a pattern.
starting at index point 0 you print the element of that index point. The next index point then becomes becomes the int of the element you just printed and the pattern continues until done.
The catch is if that index point has already been used you move one to the left until you reach an index point that has not been used.
Below is my solution to the problem. Everything seems to work i.e. it moves along the number as it is suppose to however when it encounters an index point that it has already used it still prints that element.
Any ideas why it doesn't appear to be skipping to the left properly?
Output is:
If L is: L = [1, 4, 4, 1, 2, 4, 3]
N is: 1, 4, 2, 4, 2, 4, 2] when it should
[1, 4, 2, 4, 1, 4, 3]
# other way around
L = [1, 4, 4, 1, 2, 4, 3]
for index, s in enumerate(L):
print(index, s)
print(' ', L)
M = []
N = []
T = []
i = L[0]
index_position = 0
while len(T) != len(L):
if index_position in T:
index_position = index_position + 1
else:
N.append(i)
T.append(index_position)
index_position = i
i = L[index_position]
print('N is: ', N)
print('T is: ', T)
seen_that_before = []
N = []
for number in L
if number in seen_that_before: continue
seen_that_before.append(number)
N.append(number)
Something like that?
Please use significant variable names. N, T, L or i are confusing.

Sorting repeated elements

What I try to do is to write a function sort_repeated(L) which returns a sorted list of the repeated elements in the list L.
For example,
>>sort_repeated([1,2,3,2,1])
[1,2]
However, my code does not work properly. What did I do wrong in my code?
def f5(nums):
count = dict()
if not nums:
for num in nums:
if count[num]:
count[num] += 1
else:
count[num] = 1
return sorted([num for num in count if count[num]>1])
return []
if count[num]: will fail if the dictionary doesn't have the key already. Take a look at the various counter recipes on this site and use one instead.
Also, not nums is true if nums is an empty sequence, which means that the loop body will never be executed. Invert the condition.
Use a counter and check for values greater than 1
from collections import Counter
def sort_repeated(_list):
cntr = Counter(_list)
print sorted([x for x in cntr.keys() if cntr[x] > 1])
sort_repeated([7, 7, 1, 2, 3, 2, 1, 4, 3, 4, 6, 5])
>> [1, 2, 3, 4, 7]

Transform a flat list to nested List

Using Python
I want the following:
[1, 2, 2, 1, 2, 3, 2, 3]
To be transformed into:
[1, 2, 2, [1, 2, 3], 2, 3]
Rules: Go through each item in the list. If we hit a 2 followed by a 1 created a list and include that 1 in that list until we hit a 3, include that 3, then close the list and continue. It's like if 1 was 3 were parenthesis.
I'm not very good with recursive algorithms which I think might be needed in this case.
Thanks as always.
Still keeping in mind that #Walter is correct in his comments to your question, this is a silly implementation of what you asked for, inspired by the final bit of your question, in which you suggest that 1 and 3 could just be replaced with [1 and 3].
>>> import re
>>> s = repr([1, 2, 2, 1, 2, 3, 2, 3])
>>> s = re.sub('1', '[1', s)
>>> s = re.sub('3', '3]', s)
>>> l = eval(s)
>>> l
[[1, 2, 2, [1, 2, 3], 2, 3]]
What it does is working on the representation of the list (a string) and substituting the way you suggested using regular expressions. Finally, it evaluate the string (getting back a list).
I call this implementation "silly" because it does the trick, but it's ugly and truly unpythonic. That said, it does the trick, so if you are simply using it for a one-off conversion of some data you need to use...
HTH!
def whatever(a):
b = []
tmp = []
last = None
for elem in a:
if tmp:
tmp.append(elem)
if elem == 3:
b.append(tmp)
tmp = []
elif last == 2 and elem == 1:
tmp.append(1)
else:
b.append(elem)
last = elem
return b
print whatever([1, 2, 2, 1, 2, 3, 2, 3])
That is an entertaining problem! Here is my solution:
def treeize(treeizable, tree=None, stopper=object()):
if tree is None:
tree = []
if treeizable[:1] == [stopper]:
tree.append(treeizable.pop(0))
return tree
elif treeizable[0:2] == [2, 1]:
tree.append(treeizable.pop(0))
subtree = []
treeize(treeizable, subtree, stopper=3)
tree.append(subtree)
return treeize(treeizable, tree, stopper)
elif treeizable:
tree.append(treeizable.pop(0))
return treeize(treeizable, tree, stopper)
else:
return tree
This function receives a flat list treeizable that should be converted to a nested list tree. The stopper parameter marks when the current list is done - being this a nested or the toplevel list. (Since the default value of stopper is an instance of object, it is impossible that there will be a stopper on a list called with the default value, because instances of object are different between themselves).
def treeize(treeizable, tree=None, stopper=object()):
For easing our work, the default value of tree is None and, if it has the default value, then it is set to a list. It is made because it is problematic to have mutable values as default parameter objects. Also, it would be annoying to have to type the function with an empty list everytime.
if tree is None:
tree = []
If the first value of the flat list is the "stopper", then it is added to the tree and the tree is returned. Note that, by using treeizable.pop(0) I am actually removing the value from the flat list. Since the stopper is only set when defining a nested list so, when we found it, no more need to be done: the "subtree" (that is, the nested list) is complete. Also, note that I get the first element of the list with a slice of the list. I made it because it is boring to have to type if treeizable and treeizable[0] == stopper. Since slicing does not have problems with inexistent indexes, I got the slice and compared it to another list made in place with only the stopper:
if treeizable[:1] == [stopper]:
tree.append(treeizable.pop(0))
return tree
If the beginning of the list is the "beginner", then I pop the first element from the list, append it to the tree and create a new tree - that is, a empty list. Now I call treeize() with the remaining list and the empty subtree, also passing 3 as the stopper value. treeize() will recursively generate a new tree that I append to my initial tree. After that, just call treeize() with the remaining of the list (which does not contain the elements of the subtree anymore) and the original list. Note that the stopper should be the same stopper received by the original call.
elif treeizable[0:2] == [2, 1]:
tree.append(treeizable.pop(0))
subtree = []
treeize(treeizable, subtree, stopper=3)
tree.append(subtree)
return treeize(treeizable, tree, stopper)
If none of the previous conditions (the first element is a stopper, the beginning of the list is [2, 1]) is true, then I verify if there is something in the list. In this case, I pop the first element, add to the tree and call treeize() with the rest of the list.
elif treeizable:
tree.append(treeizable.pop(0))
return treeize(treeizable, tree, stopper)
In the case that not even the previous condition is true... then we have an empty list. This means that all elements were put in the tree. Just return the tree to the user:
else:
return tree
This seems to have worked:
>>> treeize.treeize([1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 3, 2, 4, 5, 3, 3, 2, 3, 4])
[1, 2, 2, [1, 2, 2, [1, 2, 2, [1, 2, 3], 2, 4, 5, 3], 3], 2, 3, 4]
Your question has a taste of homework. In principle, we should not answer it but it is so interesting that I couldn't help myself :) If it is a homework, however, do not try to use this solution as your because it would be wrong and your teacher would surely find it on Google :P
I like state machines:
from itertools import izip, tee
def pairwise(iterable):
a, b = tee(iterable)
next(b)
return izip(a, b)
class Flat(object):
def append_next(self, alist, e0, e1):
alist.append(e0)
if e0 == 2 and e1 == 1:
alist.append([])
self.__class__ = Nested
def append_last(self, alist, e):
alist.append(e)
class Nested(object):
def append_next(self, alist, e0, e1):
alist[-1].append(e0)
if e0 == 3:
self.__class__ = Flat
def append_last(self, alist, e):
alist[-1].append(e)
def nested(flat_list):
if len(flat_list) <= 1:
return list(flat_list)
state = Flat()
nested_list = []
for x, y in pairwise(flat_list):
state.append_next(nested_list, x, y)
state.append_last(nested_list, y)
return nested_list
s = [1, 2, 2, 1, 2, 3, 2, 3]
print nested(s)
gives:
[1, 2, 2, [1, 2, 3], 2, 3]
But this might be more pythonic:
def nested(flat_list):
if len(flat_list) <= 1:
return list(flat_list)
pairs = pairwise(flat_list)
nested_list = []
while True:
for x, y in pairs:
nested_list.append(x)
if x == 2 and y == 1:
nested_list.append([])
break
else:
nested_list.append(y)
break
for x, y in pairs:
nested_list[-1].append(x)
if x == 3:
break
else:
nested_list[-1].append(y)
break
return nested_list
Pease bear with me - it is 2:50(night) - here is my version - not very beatiful but it works pretty well for me:
def buildNewList(inputList):
last = 0
res = []
for i,c in enumerate(inputList):
if i == 0:
prev = c
if i < last:
continue
if c == 1 and prev == 2:
if 3 in inputList[i:]:
last = i + 1 + inputList[i:].index(3)
res.append(buildNewList(inputList[i: last]))
else:
last = len(inputList)
res.append(buildNewList(inputList[i:len(inputList)]))
else:
res.append(c)
prev = c
return res
l1 = buildNewList([1, 2, 2, 1, 2, 3, 2, 3])
>>> [1, 2, 2, [1, 2, 3], 2, 3]
l2 = buildNewList([1, 2, 2, 1, 2, 3, 2, 1, 2, 3])
>>> [1, 2, 2, [1, 2, 3], 2, [1, 2, 3]]
l3 = buildNewList([1,2,3,1,2,3])
>>> [1, 2, 3, 1, 2, 3]
l4 = buildNewList([1,2,1,1,2,1])
>>> [1, 2, [1, 1, 2, [1]]]

Categories

Resources