Related
How I find the longest sub-list in list of number pairs that has the difference of 1.
So "number neighbors" could be element 1 and 2 or element 7 and 6.
If the list is [7, 1, 2, 5, 7, 6, 5, 6, 3, 4, 2, 1, 0],
Then the desired output should be 4. The sub-list would be then [7, 6, 5, 6].
This is what I have for now. The for loop formula is really broken and I don't know how to solve this.
list = [7, 1, 2, 5, 7, 6, 5, 6, 3, 4, 2, 1, 0]
sublist = []
for i in list:
if list[i] - list[i+1] == 1 or list[i] - list[i+1] == -1:
sublist.append(i)
print(sublist)
print(len(sublist))
more-itertools makes it simple:
from more_itertools import split_when
lst = [7, 1, 2, 5, 7, 6, 5, 6, 3, 4, 2, 1, 0]
print(max(split_when(lst, lambda x, y: abs(x - y) != 1), key=len))
Its best to break these types of problems up into their parts
the main problem here is to get all sequential sequences
def get_sequences_iter(an_array):
# start a new sequence with first value (or empty)
sequence = an_array[:1]
# check each index with the value that comes before
for idx in range(1,len(an_array)):
if an_array[idx] - an_array[idx-1] in {1,-1}:
# this is part of a run append it
sequence.append(an_array[idx])
else:
# run is broken
yield sequence
# start a new run
sequence = [an_array[idx]]
#capture final sequence
yield sequence
once you have this you can get all the runs in a list in O(n) time
sequences = get_sequences_iter([7, 1, 2, 5, 7, 6, 5, 6, 3, 4, 2, 1, 0])
for sequence in sequences:
print(sequence)
hopefully with this information you can figure out how to solve your actual question
but just in case
print(max(sequences,key=len))
I'm trying to find a way of going through a loop of a single list skipping the first element each time.
so for example, if I have a list:
lst = [0,1,2,3,4,5,6]
and wish to use a for loop to cycle through all but the first element and stop at an arbitrary point. So if I wish to start at index 1 of lst and advance through a cycle of each element (excluding the first) I can use the following:
scd = [1,2,3,4,5,6]
out = []
for i in range (1,14+1):
if (i%len(lst)) not in scd:
continue
else:
out.append(lst[i%len(lst)])
print(out)
it returns a list with only 12 elements:
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
The output that I'm trying to get is:
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2]
I know the issue is in using the continue in the for loop, but I'm struggling with a workaround that gets me the desired output.
Any help would be greatly appreciated. also if there's a more pythonic way of going about this problem, I'm all ears.
Thanks so much.
IIUC, you simply want to repeat the same list, right? How about this where you could concatenate lists using divmod:
num = 14
i,j = divmod(num, len(lst)-1)
out = lst[1:] * i + lst[1:1+j]
Output:
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2]
I've come up with this code to sort out duplicates in a randomly arranged list of numbers.
counter = 0
randomDup_list = [0, 3, 0, 1, 9, 8, 2, 3, 4, 2, 4, 3, 5, 6, 0, 6, 5, 2, 6, 6, 7, 8, 9, 4, 4]
dup_sorted = []
for x in randomDup_list:
if len(randomDup_list) == 0:
dup_sorted.append(x)
counter +=1
elif x != randomDup_list[counter]:
for y in dup_sorted:
if y != x:
dup_sorted.append(x)
print(dup_sorted)
When I run the code there are no errors but the numbers don't seem to be appending to my new list, and it comes out blank like this: [].
The most pythonic way to do this is with a list comprehension, like so:
dup_sorted = [el for index, el in enumerate(randomDup_list) if el not in randomDup_list[:index]]
Enumerate will create a list of tuples with the first tuple element as the index in the list, [(0,0), (1,3), (2,0), ...] are the first 3 elements in your case.
Then it basically checks if el is the first occurence of el in the list and if it is, it adds el to the dup_sorted list.
List comprehensions are maybe hard to understand, but there is plenty of information about them on the internet. Good luck with learning Python!
I did not understand what you want but you can basically sort the list like that
print(sorted(randomDup_list))
and you can create your new list like that
dup_sorted = sorted(randomDup_list)
print(dup_sorted)
Hey welcome to learning python. I have been coding for a couple of years but I still use print to test my logic.
Lets break down your code and add print to each logic test
counter = 0
randomDup_list = [0, 3, 0, 1, 9, 8, 2, 3, 4, 2, 4, 3, 5, 6, 0, 6, 5, 2, 6, 6, 7, 8, 9, 4, 4]
dup_sorted = []
for x in randomDup_list:
print("start iteration")
if len(randomDup_list) == 0:
print("1 true")
dup_sorted.append(x)
counter +=1
elif x != randomDup_list[counter]:
print("2 true")
print(dup_sorted)
for y in dup_sorted:
if y != x:
print("3 true")
dup_sorted.append(x)
print("stop iteration")
print(dup_sorted)
If you run this code you will see that the first logic test will never be true in your example. So it will go to the second logic test. This will eventually evaluate to true but there will be some iterations that will be skipped. Blank blocks of start iteration stop iteration. For the last logic test this will never be true because dup_sorted will always be empty. So for y in dup_sorted will result to nothing.
Also I think sort out is ambiguous. Is it sort? filter?
You can do set(randomDup_list) for filtering out duplicates
You can do sorted(randomDup_list) for sorting out the list
You can do sorted(list(set(randomDup_list)) for a sorted filtered list
Seeing your new comments
randomDup_list = [0, 3, 0, 1, 9, 8, 2, 3, 4, 2, 4, 3, 5, 6, 0, 6, 5, 2, 6, 6, 7, 8, 9, 4, 4]
dup_sorted = []
for x in randomDup_list:
if x in dup_sorted:
continue
else:
dup_sorted.append(x)
print(dup_sorted)
This initializes an empty list. Loops through your list. Check if it exists then appends if not. Since List maintain order, you can expect the order not to change.
To remove any duplicates from the list without changing the order
Code
dup_sorted = []
for x in randomDup_list:
if not x in dup_sorted: # check if x is in output yet
dup_sorted.append(x) # add x to output
print(dup_sorted)
# Output: [0, 3, 1, 9, 8, 2, 4, 5, 6, 7]
You can use this:
counter = 0
randomDup_list = [0, 3, 0, 1, 9, 8, 2, 3, 4, 2, 4, 3, 5, 6, 0, 6, 5, 2, 6, 6, 7, 8, 9, 4, 4]
dup_sorted = []
dup_sorted.append(randomDup_list[0])
for x in range(len(randomDup_list)):
temp = 0
for y in range(len(dup_sorted)):
if randomDup_list[x] != dup_sorted[y]:
temp = temp + 1
if temp == len(dup_sorted):
dup_sorted.append(randomDup_list[x])
print(dup_sorted)
I am doing an exercise on checkio about writing a function to exclude the unique elements in a list, and only keep the non-unique ones. I wrote the following lines.
def checkio(data):
for i in data:
if data.count(i) == 1:
data.remove(i)
return data
And then did the following tests.
checkio([1, 2, 3, 1, 3]) == [1, 3, 1, 3]
checkio([1, 2, 3, 4, 5]) == []
checkio([5, 5, 5, 5, 5]) == [5, 5, 5, 5, 5]
checkio([10, 9, 10, 10, 9, 8]) == [10, 9, 10, 10, 9]
But the second test won't pass. Instead of returning an empty array [], it returns [2,4].
Why is that?
Thanks for the help in advance!
Solution:
def checkio(data):
duplicates = []
for i in data:
if data.count(i) > 1:
duplicates.append(i)
return duplicates
Here, as mentioned by #sp4c38 instead of removing the unique elements and modifying the original list, add the duplicates to a new list.
This passes all the test-cases:
checkio([1, 2, 3, 1, 3])
checkio([1, 2, 3, 4, 5]) == []
checkio([5, 5, 5, 5, 5]) == [5, 5, 5, 5, 5]
checkio([10, 9, 10, 10, 9, 8]) == [10, 9, 10, 10, 9]
the code traps it self. The problem is that the for in data:... takes the data[0] (the first item) of your list. 1 is unique, so your program removes the 1 from your data list. data is now: [2,3,4,5]. Now the for-in loop goes on with data[1] which is now the number 3. 3 is also unique so it removes it. Your list is now: data = [2,4,5]. Now your code goes on with data[2], which is 5. It's removed. At the end there is data = [2,4] left. Try to find another solution for your problem. Hope I could help you.
Edit:
You shouldn't remove the items from the list. Try to create a new list where you put all non-unique items in it. Try to use "smaller than" and "bigger than" relations (<,>).
You can accomplish that using a single liner
def checkio(data):
return [x for x in data if data.count(x) > 1]
I faced some problem with solving the next problem:
We have a list of elements (integers), and we should return a list consisting of only the non-unique elements in this list. Without changing order of the list
I think the best way is to delete or remove all unique element.
Take note that I just start to learn python and would like only the simplest solutions.
Here is my code:
def checkio(data):
for i in data:
if data.count(i) == 1: #if element seen in the list just ones, we delet this el
ind = data.index(i)
del data[ind]
return data
Your function can be made to work by iterating over the list in reverse:
def checkio(data):
for index in range(len(data) - 1, -1, -1):
if data.count(data[index]) == 1:
del data[index]
return data
print(checkio([3, 3, 5, 8, 1, 4, 5, 2, 4, 4, 3, 0]))
[3, 3, 5, 4, 5, 4, 4, 3]
print(checkio([1, 2, 3, 4]))
[]
This works, because it only deletes numbers in the section of the list that has already been iterated over.
Just I used list Comprehensions.
def checkio(data):
a=[i for i in data if data.count(i)>1]
return a
print checkio([1,1,2,2,1,1,1,3,4,5,6,7,8])
You can implement a OrderedCounter, eg:
from collections import OrderedDict, Counter
class OrderedCounter(Counter, OrderedDict):
pass
data = [1, 3, 1, 2, 3, 5, 8, 1, 5, 2]
duplicates = [k for k, v in OrderedCounter(data).items() if v > 1]
# [1, 3, 2, 5]
So you count the occurrence of each value, then filter on if it has a frequency of more than one. Inheriting from OrderedDict means the order of the original elements is preserved.
Going by comments, you want all duplicated elements reserved, so you can pre-build a set of the duplicate entries, then re-iterate your original list, eg:
from collections import Counter
data = [1, 3, 1, 2, 3, 5, 8, 1, 5, 2]
duplicates = {k for k, v in Counter(data).items() if v > 1}
result = [el for el in data if el in duplicates]
# [1, 3, 1, 2, 3, 5, 1, 5, 2]
Try this:
>>> a=[1,2,3,3,4,5,6,6,7,8,9,2,0,0]
>>> a=[i for i in a if a.count(i)>1]
>>> a
[2, 3, 3, 6, 6, 2, 0, 0]
>>> a=[1, 2, 3, 1, 3]
>>> a=[i for i in a if a.count(i)>1]
>>> a
[1, 3, 1, 3]
>>> a=[1, 2, 3, 4, 5]
>>> a=[i for i in a if a.count(i)>1]
a
[]
def checkio(data):
lis = []
for i in data:
if data.count(i)>1:
lis.append(i)
print(lis)
checkio([1,2,3,3,2,1])
Yeah it's a bit late to contribute to this thread but just wanted to put it there on the net for anyone else use.
Following what you have started, iterating on the list of integers, but not counting or deleting elements, try just testing if the element has already been seen, append it to a list of duplicated elements:
def checkio(data):
elements = []
duplicates = []
for i in data:
if i not in elements:
elements.append(i)
else:
if i not in duplicates:
duplicates.append(i)
return duplicates
d = [1, 3, 1, 2, 3, 5, 8, 1, 5, 2]
print (checkio(d))
#[1, 3, 5, 2]
numbers = [1, 1, 1, 1, 3, 4, 9, 0, 1, 1, 1]
x=set(numbers)
print(x)
You can use the set key word too to get the desired solution.
I used an integer and bool to check every time the list was modified within a while loop.
rechecks = 1
runscan = True
while runscan == True:
for i in data:
if data.count(i) <2:
data.remove(i)
rechecks+=1
#need to double check now
if rechecks >0:
runscan = True
rechecks-=1
else:
runscan = False
return data
Would it not be easier to generate a new list?
def unique_list(lst):
new_list = []
for value in lst:
if value not in new_list:
new_list.append(value)
return new_list
lst = [1,2,3,1,4,5,1,6,2,3,7,8,9]
print(unique_list(lst))
Prints [1,2,3,4,5,6,7,8,9]