Python 3.5.1 Extending a list - python

sorry to repost (I've just joined stack overflow 30 mins ago).
I don't think I explained in my previous post of my function.
def GetExtendedKeyword(message, newkeyword):
while True:
difference = len(message) - len(newkeyword)
if difference > 0:
newkeyword.extend(newkeyword[:difference]
return newkeyword
elif difference <= 0:
return newkeyword
What I have are two lists, a message and keyword list. The program calculates the difference between them and if the keyword is shorter than the message list, the program will repeat the keywordlist by that difference.
For example the original keywordlist is [0,1,5,2,5] and the difference is 3, the end result should be [0,1,5,2,5,0,1,5]. The program doesn't like my code when it comes to longer keyword or message lists. Please help!

If the amount can be larger than the list length, you can do this:
def extend(lst, n):
nfull = n / len(lst) + 1
nrem = n % len(lst)
return lst*nfull+lst[:nrem]
lst = [0,1,5,4,2,9]
print extend(lst, 3)
# [0, 1, 5, 4, 2, 9, 0, 1, 5]
print extend(lst, 7)
# [0, 1, 5, 4, 2, 9, 0, 1, 5, 4, 2, 9, 0]

list.extend(L) Extend the list by appending all the items in the
given list; equivalent to a[len(a):] = L.
It's sentence from Python Documentation. I think it is the best place where you should looking for a help. Acording to documentation, your code should look like this:
listOne = [0,1,5,4,2,9]
listOne.extend(listOne[:n])
I wonder to help you.

Try it like this
l = [0, 1, 5, 4, 2, 9]
l.extend(l[:n]) #extend l with the first n elements of l
This only works for n < len(l) ...

Related

Rotate array in Python

There is this question, 189 Rotate array on Leetcode. enter link description here Its statement is "Given an array, rotate the array to the right by k steps, where k is non-negative."
To understand it better, here's an example.
enter image description here
So, My code for this is
for _ in range(k):
j = nums[-1]
nums.remove(nums[-1])
nums.insert(0, j)
It cannot pass some of the test cases in it.
In the discussion panel, I found a code claiming it got submitted successfully that went like
for _ in range(k):
nums.insert(0, nums.pop(-1))
I would like to know, what is the difference between these two and why my code isn't able to pass some of the test cases.
If you do this on python shell [].remove.__doc__, you'll see the purpose of list.remove is to:
Remove first occurrence of value. Raises ValueError if the value is
not present.
In your code nums.remove(nums[-1]) does not remove the last item, but first occurrence of the value of your last item.
E.g.
If you have a list with values nums = [2, 4, 8, 3, 4] and if you do nums.remove(nums[-1]) the content of nums becomes [2, 8, 3, 4] not [2, 4, 8, 3] that you're expecting.
Just use slicing:
>>> def rotate(l, n):
... return l[-n:] + l[:-n]
...
>>> lst = [1, 2, 3, 4, 5, 6, 7]
>>> rotate(lst, 1)
[7, 1, 2, 3, 4, 5, 6]
>>> rotate(lst, 2)
[6, 7, 1, 2, 3, 4, 5]
>>> rotate(lst, 3)
[5, 6, 7, 1, 2, 3, 4]
In your code j = nums[-1] and you are trying to insert(0, nums[-1]).
In
for _ in range(k):
nums.insert(0, nums.pop(-1))
inserting other number - (0, nums.pop(-1))
Answer given by cesarv is good and simple, but on large arrays numpy will definitely perform better. Consider:
np.roll(lst, n)
The remove() method takes a single element as an argument and removes it's first occurence from the list.
The pop() method takes a single argument (index). The argument passed to the method is optional. If not passed, the default index -1 is passed as an argument (index of the last item).
If the test case has the same item before the last index then test case will fail.
Hence to correct your code replace remove with pop
for _ in range(k):
poppedElement = nums.pop()
nums.insert(0, poppedElement)
or to make it even concise -
for _ in range(k):
nums.insert(0, nums.pop())

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]

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]

More 'Pythonic' Way to alternate list shuffle

Trying to 'shuffle' a list with even number of items. Splitting the list, L in half and alternating taking an element from each.
I've tried pop, but that approach was unable to get me to a one-liner. (while loop) and I know there is likely some more succinct way to move through it.
The shuffle from random isn't exactly what I need, either – because that randomizes the entire order instead of alternating between the split list.
If a one-liner isn't possible, is that because it's more readable in a while loop?
def shuffle(L):
'''
I apologize in advance for how wet the following code is...
Example:
>>> shuffle([1, 2, 3, 4, 5, 6])
[1, 4, 2, 5, 3, 6]
'''
return [L[:(len(L)//2)][0], L[(len(L)//2):][0], L[:(len(L)//2)][1], L[(len(L)//2):][1], L[:(len(L)//2)][2], L[(len(L)//2):][2]]
other attempt:
def shuffle(L):
x, L_first, L_next, L = len(L), L[:(len(L)//2)], L[(len(L)//2):], []
while len(L) != x:
L.extend([L_first.pop(0), L_next.pop(0)])
return L
Use slice assignment with a step:
def shuffle(l):
result = [None] * len(l)
# Put the first half of l in the even indices of result
result[::2] = l[:len(l)//2]
# Put the second half of l in the odd indices of result
result[1::2] = l[len(l)//2:]
return result
If I understand correctly, you could also opt for itertools.chain.from_iterable after zipping to get the alternating effect.
from itertools import chain
def shuff(l):
return list(chain.from_iterable(zip(l[:len(l)//2], l[len(l)//2:])))
Demo
>>> shuff(list(range(1, 7))
[1, 4, 2, 5, 3, 6]
One possibility (requires an external library but the recipe can also be found in the itertools-recipes section) is:
from iteration_utilities import roundrobin
def shuffle(L):
return list(roundrobin(L[:len(L)//2], L[len(L)//2:]))
This is probably slower than list assignment but it also works for arbitary amounts of iterables without problems and it doesn't require odd-sized-input handling:
>>> shuffle([1, 2, 3, 4, 5, 6, 7])
[1, 4, 2, 5, 3, 6, 7]
>>> shuffle([1, 2, 3, 4, 5, 6])
[1, 4, 2, 5, 3, 6]
I did some timings and #user2357112 definetly has the fastest solution but my solution is at least on the second place (note that this graph is in log-log, that means the difference in absolute terms may seem smaller than it really is!):
Disclaimer: I'm the author of that iteration_utilities library.
list comprehension with index calculation using modulo and floor division
[ L[(i + (i % 2)*len(L))//2] for i in range(len(L)) ] # for case of even len(L)
still one line for the general case
[ L[i//2 + (i % 2)*len(L)//2] for i in range(2*(len(L)//2)) ] + [L[-1]]*(len(L) % 2)
the index calc (i + (i % 2)*len(L))//2
can be parsed as adding
i//2 which gives 0, 0, 1, 1, 2, 2 ...
and
(i % 2)*len(L)//2 where (i % 2) alternates 0, 1 for even/odd i
0, len(L)//2, 0, len(L)//2, 0, len(L)//2 ...
sum:
0, len(L)//2, 1, 1 + len(L)//2, 2, 2 + len(L)//2 ...
Found two solutions. First one is very unpythonic (using python 2.7)
a = [1, 2, 3, 4, 5, 6] # intial array
Method One (using string magic):
[int(p) for p in ' '.join([str(x) + ' ' + str(y) for x, y in zip(a[:len(a) / 2], a[len(a) / 2:])]).split(' ')]
Method Two:
[i for Tuple in zip(a[:len(a) / 2], a[len(a) / 2:]) for i in Tuple]

Contracting in python

I'm supposed to write a program that contracts a list. For example:
[1, 3, 4, 5, 1, 8, 6,]
has to be contracted into a list that looks like this:
[1, 5, 1, 8, 6, 6]
I don't have a clue on how to do this and was hoping that any of you could help me.
I'm given a list that looks like this l1 = [1, 3, 9, 1, 2, 7, 8] and i'm supposed to contract the list into a new list which consist of the old lists nondecending segments extremities. It is supposed to work with any list given.
Let me try to understand the question:
im given a list that looks like this l1 = [1, 3, 9, 1, 2, 7, 8] and im
supposed to contract the list by taking the first number then the next
bigest and the smallest after that and then the biggest again. This is
a school assignment and i have no idea on how to do this. english
isn't my first language and it's realy difficult to explain the
assignment :/
I supposed that "biggest" and "smallest" refer to local maxima and minima. So a number at index i is "biggest" if l[i-1] < l[i] and l[i] > l[i+1]. "Smallest" the other way around. So basically your are searching for the extrema of a function N -> N.
If this is what you want, this should help (considering that start and end points always are extrema):
#! /usr/bin/python3.2
def sign(x): return 0 if not x else x // abs(x)
def extrema (l):
return [l[0]] + [e for i, e in enumerate(l[:-1]) if i and sign(e-l[i-1])==sign(e-l[i+1])] + [l[-1]]
l1 = [1, 3, 9, 1, 2, 7, 8]
print (extrema (l1))

Categories

Resources