Using a list to multiply a value? - python

n1 = 20*values[0]
n2 = 100*values[1]
print(n1,"\n",n2)
I've basically got a list above this, with a few values, only if I would have
currently if i have 3 in the first value and 7 in the second, 3 would show up 20 times, and 7 would show up 100 times,
however i would like it to be just multiplied.
Is there any way to do this without importing anything?
--edited again--
I Should have said this much sooner but i didn't realise inputted values would change anything, or factor into anything of this
top of the code i have:
for num in numbers:
values.append(num)
with values being an empty list, and "numbers" is the Input

I think this is what you want
>>> values = [3,7]
>>> n1 = 20 * [values[0]]
>>> n2 = 5 * [values[1]]
>>> print n1
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
>>> print n2
[7, 7, 7, 7, 7]

number * list_value = product
In [1752]: values = [3, 7]
In [1753]: 20 * values[0]
Out[1753]: 60

When you multiply by an int, the math functions take over. However, in order for repetition, just convert to a str then multiply:
n1 = 20*str(values[0])
n2 = 100*str(values[1])
print(n1,"\n",n2)

If you have a list of values and another list of numbers to multiply the corresponding values with:
values = [12, 14]
multiples = [20, 100]
Then, you can get what you want with:
result = [value * multiple for value, multiple in zip(values, multiples)]
See zip and list comprehensions.
If, on the other hand, you want to repeat the elements in values by the elements in multiples, you can do:
def repeat(values, repeats):
for value, rep in zip(values, repeats):
for _ in range(rep):
yield value
Now, you can use repeat() as a generator to do what you want:
>>> list(repeat([3, 7], [5, 10])
[3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7]

Related

How to remove an element from a list x amount of times?

I want to remove a number by an x amount of times from a list. For example, for this list [1, 4, 3, 6, 4, 3, 2, 4, 8, 11] if I wanted to remove the integer 4 by 2 times, the list would look like this: [1, 3, 6, 3, 2, 4, 8, 11]. What code would be efficient in this situation?
The code I have in the moment:
int_list = [1, 4, 3, 6, 4, 3, 2, 4, 8, 11]
result = []
remove = int(input('remove: '))
times = int(input('times: '))
for i in int_list:
if i != remove:
result.append(i)
elements = result
print(elements)
Working in-place
The list method remove removes the first occurrence of the argument from the list. So you can simply call it x amount of times on the list:
int_list = [1, 4, 3, 6, 4, 3, 2, 4, 8, 11]
remove = 4
times = 2
for _ in range(times):
int_list.remove(remove)
print(int_list)
Will give:
[1, 3, 6, 3, 2, 4, 8, 11]
Handling errors
In case the element is not found, remove will raise an error. If you want to avoid that:
Check the input pre-hand by making sure there are enough elements to remove using the count method:
if int_list.count(remove) <= times:
# rest of code
If you want to just remove all possible elements, add a check before the remove call:
for _ in range(times):
if remove in int_list:
int_list.remove(remove)
Returning a new list
You can of course simply create a copy of the input list (res = int_list.copy()) and then apply the in-place solution from above. Otherwise, to create a completely new list, use times as a counter for how many times to "skip" the wanted number:
int_list = [1, 4, 3, 6, 4, 3, 2, 4, 8, 11]
remove = 4
times = 2
res = []
for num in int_list:
if num == remove and times > 0:
times -= 1
continue
res.append(num)
print(res)
In this case there is no error handling to make. We are simply ignoring the required element a given amount of times. If it doesn't exist at all, less, or more times than given - nothing will happen.

Return a list of Element by discarding the Sequential Occurrence of Elements

i/p 1:
test_list = [1, 1, 3, 4, 4, 4, 5,6, 6, 7, 8, 8, 6]
o/p
[3, 5, 7, 6]
Exp: Since (1 1), (4 4 4) (6 6) (8 8) are in consecutive occurrence so resultant list has no addition of 6 but for last occurrence where 8, 6 are not in multiple consecutive occurrence so 6 is valid
in last iteration
i/p 2:
test_list = [1, 1, 3, 4, 4, 4, 5,4,6, 6, 7, 8, 8, 6]
o/p
[3, 5,4, 7, 6]
** like wise for 2nd input 4,4,4 is not valid but 5,4 is valid
Any suggestion for the expected o/p?
(I am looking for bit elaborated algorithm)
You can use itertools.groupby to group adjacent identical values, then only keep values that have group length of 1.
>>> from itertools import groupby
>>> test_list = [1, 1, 3, 4, 4, 4, 5,6, 6, 7, 8, 8, 6]
>>> [k for k, g in groupby(test_list) if len(list(g)) == 1]
[3, 5, 7, 6]
>>> test_list = [1, 1, 3, 4, 4, 4, 5,4,6, 6, 7, 8, 8, 6]
>>> [k for k, g in groupby(test_list) if len(list(g)) == 1]
[3, 5, 4, 7, 6]
First of all, you need to know that increasing i in your for loop does not change the value of i.
You can check it by runin this code:
for i in range(5):
print(i)
i = 2
This code will print 0 1 2 3 4 not 0 2 2 2 2 as you might think.
Going back to your question. I would use groupby from itertools, but since you specified you don't want to use it, I would do something like this:
if test_list[0] != test_list[1]: # <-- check if first element should belong to result
res_list.append(test_list[0])
for i in range(len(test_list[1:-1])): # Here we use input list, but without first and last element.
if test_list[i+1] == test_list[i+2] or test_list[i+1] == test_list[i]:
continue
else:
res_list.append(test_list[i+1])
if test_list[-2] != test_list[-1]: # <-- check if last element should belong to result
res_list.append(test_list[-1])

How can I compare a value in a list with the others but not itself?

I want to take the value of an integer in a list, and compare it to all the other integers in the list, except for itself. If they match, I want to subtract 1 from the other integer. This is the code I have:
for count6 in range(num_players):
if player_pos[count6] == player_pos[count5]:
if not player_pos[count5] is player_pos[count5]:
player_pos[count6] -= 1
I've tried a few other things, but I can't seem to make it work. I was able to get it to subtract 1 from every value, but it included the original value. How can I make this work?
Here's a simple way, just loop through each index and decrement if the value is the same, but the index is not the one you're checking against:
#!/usr/bin/env python3
nums = [3, 4, 5, 5, 6, 5, 7, 8, 9, 5]
pos = 3
print("List before: ", nums)
for idx in range(len(nums)):
if nums[idx] == nums[pos] and idx != pos:
nums[idx] -= 1
print("List after : ", nums)
which outputs:
paul#local:~/Documents/src/sandbox$ ./list_chg.py
List before: [3, 4, 5, 5, 6, 5, 7, 8, 9, 5]
List after : [3, 4, 4, 5, 6, 4, 7, 8, 9, 4]
paul#local:~/Documents/src/sandbox$
All the 5s have been decremented by one, except for the one at nums[3] which is the one we wanted to leave intact.
I think you're looking for something like this:
>>> values = [1, 3, 2, 5, 3, 8, 1, 5]
>>> for index, value in enumerate(values):
... for later_value in values[index + 1:]:
... if value == later_value:
... values[index] = values[index] - 1
...
>>> values
[0, 2, 2, 4, 3, 8, 1, 5]
This decrements each value by the number of times it occurs later in the list. If you want to decrement each value by the number of times it appears EARLIER in the list, you could reverse the list first and then re-reverse it after.
I'm not sure about "but included the original value" means, i'm trying to use the following code, hope this is what you want :
>>> num_players = 4
>>> player_pos = [3, 4, 5, 6]
>>> count5 = 2
>>> for count6 in range(num_players):
if player_pos[count6] <> player_pos[count5]:
player_pos[count6] -= 1
>>> player_pos
[2, 3, 5, 5]

Smallest number in a particular part of my list

I have a question about python. I have to sort a list of random numbers in a particular way (it's not allowed to use sort()). I'll try to explain:
I have to search for the smallest number, and swap this number with the number at the first position in the list.
Then, I search again for the smallest number, but this time ignore the first number in my list because this one is already sorted. So, I should start searching for the smallest number from the second number (index 1) till the end of the list. The smallest number then found, should be swapped with the second number in the list(so the index 1).
I hope you understand my problem. This is the code I wrote so far, but I get errors and/or the sorting isn't correct.
array = random_integers(10,size=10)
my_list = list(array)
for i in range(len(my_list)):
print my_list
a = min(my_list[i:len(my_list)])
b = my_list.index(a)
my_list[i],my_list[b]=my_list[b],my_list[i]
print my_list
I think there's a problem in my range, and a problem with the
a = min(my_list[i:len(my_list)])
I want to search for the smallest number, but not in the ENTIRE list how can I do this?
The problem occurs on this line:
b = my_list.index(a)
since this searches for the first occurrence of a in all of my_list. If the same number occurs twice, then b will always correspond to the smallest such index, which might be less than i. So you might end up moving a number which has already been sorted.
The obvious thing to try is to slice my_list before calling index:
my_list[i:].index(a)
but note that index will return values between 0 and N-i. We want numbers between i and N. So be sure to add i to the result:
b = my_list[i:].index(a)+i
Thus, the easiest way to fix your code as it presently exists is:
for i in range(len(my_list)):
a = min(my_list[i:])
b = my_list[i:].index(a)+i
my_list[i], my_list[b] = my_list[b], my_list[i]
but notice that min is searching through all the items in my_list[i:] and then the call to index is traversing the same list a second time. You could find b in one traversal like this:
b = min(range(i, N), key=my_list.__getitem__)
Demo:
import numpy as np
array = np.random.random_integers(10,size=10)
my_list = list(array)
N = len(my_list)
for i in range(N):
b = min(range(i, N), key=my_list.__getitem__)
my_list[i], my_list[b] = my_list[b], my_list[i]
print my_list
yields
[3, 10, 9, 6, 5, 3, 6, 8, 8, 4]
[3, 3, 9, 6, 5, 10, 6, 8, 8, 4]
[3, 3, 4, 6, 5, 10, 6, 8, 8, 9]
[3, 3, 4, 5, 6, 10, 6, 8, 8, 9]
[3, 3, 4, 5, 6, 10, 6, 8, 8, 9]
[3, 3, 4, 5, 6, 6, 10, 8, 8, 9]
[3, 3, 4, 5, 6, 6, 8, 10, 8, 9]
[3, 3, 4, 5, 6, 6, 8, 8, 10, 9]
[3, 3, 4, 5, 6, 6, 8, 8, 9, 10]
[3, 3, 4, 5, 6, 6, 8, 8, 9, 10]
If you want the smallest number from a list you can use min(). If you want a part of a list you can use list slicing: my_list[1:]. Put the two together and you get the smallest number from a part of your list. However, you don't need to do this, as you can .pop() from the list instead.
sorted_list = []
while my_list:
n = min(my_list)
sorted_list.append(my_list.pop(my_list.index(n)))
If you're using numpy arrays then instead of my_list.index(min(my_list)) you can use the .argmin() method.
While this type of sorting is good for an introduction, it is not very efficient. You may want to consider looking at the merge sort, and also the Python's built-in timsort.

swapping one number with two numbers in a list in python

If I am given a list of numbers and I want to swap one of them with the next two numbers.
Is there a way to do this in one shot, without swapping the first number twice?
To be more specific, let's say I have the following swap function:
def swap_number(list, index):
'''Swap a number at the given index with the number that follows it.
Precondition: the position of the number being asked to swap cannot be the last
or the second last'''
if index != ((len(list) - 2) and (len(list) - 1)):
temp = list[index]
list[index] = list[index+1]
list[index+1] = temp
Now, how do I use this function to swap a number with the next two numbers, without calling swap on the number twice.
For example: I have the following list: list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Now, how do I swap 3 with the 4 and 5 in one shot?
The expected output would be
list = [0, 1, 2, 4, 5, 3, 6, 7, 8, 9]
Something like this?
def swap(lis, ind):
lis.insert(ind+2, lis.pop(ind)) #in-place operation, returns `None`
return lis
>>> lis = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> lis = swap(lis, 3)
>>> lis
[0, 1, 2, 4, 5, 3, 6, 7, 8, 9]

Categories

Resources