I have user entered numbers but when I entered in descending order then only list is sorted else it's not.
values = input("Enter the number")
values1 = input("Enter the number")
values2 = input("Enter the number")
templist = values.split(","),values1.split(","),values2.split(",")
print('List : ',templist)
finallist = sorted(templist)
print('Final List : ',finallist)
When you use sorted(templist) you tuple of lists gets sorted and not the inner list!
You need to iterate through your inner list and sort them separately like,
map(sorted,templist)
or
[sorted(l) for l in templist]
That is,
>>> values = input("Enter the number")
Enter the number"5,4,3,2,1"
>>> values1 = input("Enter the number")
Enter the number"9,8,7,6"
>>> values2 = input("Enter the number")
Enter the number"8,6,4,2"
>>> templist = values.split(","),values1.split(","),values2.split(",")
>>> templist
(['5', '4', '3', '2', '1'], ['9', '8', '7', '6'], ['8', '6', '4', '2'])
>>> print('List : ',templist)
('List : ', (['5', '4', '3', '2', '1'], ['9', '8', '7', '6'], ['8', '6', '4', '2']))
>>> sorted(templist)
[['5', '4', '3', '2', '1'], ['8', '6', '4', '2'], ['9', '8', '7', '6']]
>>>
>>> map(sorted,templist)
[['1', '2', '3', '4', '5'], ['6', '7', '8', '9'], ['2', '4', '6', '8']]
>>>
>>> #or
...
>>> [sorted(l) for l in templist]
[['1', '2', '3', '4', '5'], ['6', '7', '8', '9'], ['2', '4', '6', '8']]
This is sorting list of strings.
If you want to sort list of integers,
>>> [sorted(int(n) for n in l) for l in templist]
[[1, 2, 3, 4, 5], [6, 7, 8, 9], [2, 4, 6, 8]]
Related
I am pretty new to python and am trying to learn how to manipulate lists. This is stumping me and I am sure it is very easy to do without a hundred lines of code with if statements which is the only way I can think to do it.
Setup:
tileNUMS = ['4', '2', '4', '4', '2', '3', '4', '2', '2', '4', '1', '2', '2', '4', '3', '2', '2', '4', '3', '2', '4', '4', '3', '4', '4', '4', '4', '4']
TileList = [tileNUMS[i:i+4] for i in range (0, len(tileNUMS),4)]
Returns:
[['4', '2', '4', '4'], ['2', '3', '4', '2'], ['2', '4', '1', '2'], ['2', '4', '3', '2'], ['2', '4', '3', '2'], ['4', '4', '3', '4'], ['4', '4', '4', '4']]
The two outside numbers are values, and the two inside numbers are position.
What I would like is if the middle two values are repeated i.e. '4', '3' above, then only the last value of that repetition gets added to the list.
i.e.
[['4', '2', '4', '4'], ['2', '3', '4', '2'], ['2', '4', '1', '2'], ['4', '4', '3', '4'], ['4', '4', '4', '4']]
After cleaning repeated positions, I want to end up with a list with every position (middle two numbers) from '1', '1' to '4', '4' and the value of that tile as the third item in the list, including 0 as a value if it is not present in the original list.
i.e.
[['1', '1', 0], ['1', '2', 0], ['1', '3', 0], ['1', '4', 0], ['2', '1', 0], ... ['4', '4', '4']
I hope this makes sense. Thank you!!
Now that's a unique list manipulation..
Does every "tile" (4 elements list) always has first and last same elements?
Let's assume it does so I will treat each tile as a 3 elements list.
I took the liberty to change some more stuff, like using ints , not str to save your data.
I'd recommend dictionaries.
This should put you in a good start:
tile_nums = ['4', '2', '4', '4', '2', '3', '4', '2', '2', '4', '1', '2', '2', '4', '3', '2', '2', '4', '3', '2', '4', '4', '3', '4', '4', '4', '4', '4']
ROW_INDEX_POSITION = 1
COL_INDEX_POSITION = 2
VALUE_POSITION = 0
BATCH_LEN = 4
tile_list = [tile_nums[i: i + BATCH_LEN] for i in range (0, len(tile_nums), BATCH_LEN)]
# dict would allow us to keep a UNIQUED collection which saves the latests values.
only_latest_indexes = dict(((int(tile[ROW_INDEX_POSITION]), int(tile[COL_INDEX_POSITION])), int(tile[VALUE_POSITION])) for tile in tile_list)
result = {}
for i in range(1, BATCH_LEN + 1):
for j in range(1, BATCH_LEN + 1):
result[(i, j)] = only_latest_indexes.get((i, j), 0)
print(result)
To just remove duplicates:
>>> set(tuple(x) for x in tile_nums)
{('2', '3', '4', '2'), ('4', '4', '3', '4'), ('4', '2', '4', '4'), ('2', '4', '1', '2'), ('2', '4', '3', '2'), ('4', '4', '4', '4')}
I'd change the values to int types instead of str types, and use tuple objects instead of list objects to hold them, like so:
>>> x = [tuple(int(i)for i in x) for x in tile_nums]
>>> x
[(4, 2, 4, 4), (2, 3, 4, 2), (2, 4, 1, 2), (2, 4, 3, 2), (2, 4, 3, 2), (4, 4, 3, 4), (4, 4, 4, 4)]
if you need to use the numbers as strings later, just convert them.
From a list of numbers, I'd like to randomly create 5 lists of 5 numbers.
import random
def team():
x = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
y = []
Count = 0
count = 0
while Count < 5:
while count<5:
count += 1
z = random.choice(x)
y += z
x.remove(z)
print(y)
Count +=1
team()
Output:
Expected Output:
I want something like 5 groups of non-repeating numbers
change the code to
import random
def team():
Count = 0
while Count < 5:
x = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
y = []
count = 0
while count<5:
count += 1
z = random.choice(x)
y += z
x.remove(z)
print(y)
Count +=1
team()
in fact, for your original code, the count becomes 5 and break the second for loop. but next time, your count is still 5, so it doesn't go into the second for loop.
You just print the first got y five 5 times.:)
This is a one-liner if you use a nested list comprehension. Also we can just directly sample the integers 0..9 instead of your list of string ['0', '1',...,'9']
import random
teams = [[random.randrange(10) for element in range(5)] for count in range(5)]
# Here's one example run: [[0, 8, 5, 6, 2], [6, 7, 8, 6, 6], [8, 8, 6, 2, 2], [0, 1, 3, 5, 8], [7, 9, 4, 9, 6]]
or if you really want string output instead of ints:
teams = [[str(random.randrange(10)) for element in range(5)] for count in range(5)]
[['3', '8', '2', '5', '3'], ['7', '1', '9', '7', '9'], ['4', '8', '0', '4', '1'], ['7', '6', '5', '8', '2'], ['6', '9', '2', '7', '3']]
or if you really want to randomly sample an arbitrary list of strings:
[ random.sample(['0','1','2','3','4','5','6','7','8','9'], 5) for count in range(5) ]
[['7', '1', '5', '3', '0'], ['7', '1', '6', '2', '8'], ['3', '0', '9', '7', '2'], ['5', '1', '7', '3', '2'], ['6', '2', '5', '0', '3']]
I know that you can swap 2 single indexes in Python
r = ['1', '2', '3', '4', '5', '6', '7', '8']
r[2], r[4] = r[4], r[2]
output:
['1', '2', '5', '4', '3', '6', '7', '8']
But why can't you swap 2 slices of indexes in python?
r = ['1', '2', '3', '4', '5', '6', '7', '8']
I want to swap the numbers 3 + 4 with 5 + 6 + 7 in r:
r[2:4], r[4:7] = r[4:7], r[2:4]
output:
['1', '2', '5', '6', '3', '4', '7', '8']
expected output:
['1', '2', '5', '6', '7', '3', '4', '8']
What did I wrong?
output:
The slicing is working as it should. You are replacing slices of different lengths. r[2:4] is two items, and r[4:7] is three items.
>>> r = ['1', '2', '3', '4', '5', '6', '7', '8']
>>> r[2:4]
['3', '4']
>>> r[4:7]
['5', '6', '7']
So when ['3', '4'] is replaced, it can only fit ['5', '6'], and when ['5', '6', '7'] is replaced, it only gets ['3', '4']. So you have ['1', '2',, then the next two elements are the first two elements from ['5', '6', '7'] which is just ['5', '6', then the two elements from ['3', '4' go next, then the remaining '7', '8'].
If you want to replace the slices, you have to start slices at the right places and allocate an appropriate size in the array for each slice:
>>> r = ['1', '2', '3', '4', '5', '6', '7', '8']
>>> r[2:5], r[5:7] = r[4:7], r[2:4]
>>> r
['1', '2', '5', '6', '7', '3', '4', '8']
old index: 4 5 6 2 3
new index: 2 3 4 5 6
Think of this:
r[2:4], r[4:7] = r[4:7], r[2:4]
as similar to this:
original_r = list(r)
r[2:4] = original_r[4:7]
r[4:7] = original_r[2:4]
So, by the time it gets to the third line of that, the 4th element isn't what you think it is anymore... You replaced '3', '4' with '5', '6', '7', and now the [4:7] slice starts with that '7'.
>>> r = ['1', '2', '3', '4', '5', '6', '7', '8']
>>> r[2:5], r[5:7] = r[4:7], r[2:4]
>>> r
['1', '2', '5', '6', '7', '3', '4', '8']
In your code:
>>> r[2:4], r[4:7] = r[4:7], r[2:4]
You are assigning r[4:7] which have 3 elements to r[2:4] which have only 2.
In the code I posted:
>>> >>> r[2:5], r[5:7] = r[4:7], r[2:4]
r[4:7] which is ['5', '6', '7'], replaces
r[2:5] which is ['3', '4', '5']
r resulting in ['1', '2', '5', '6', '7', '6', '7', '8']
and then:
r[2:4] which was ['3', '4'], replaces
r[5:7] which is ['6', '7']
So final result being:
['1', '2', '5', '6', '7', '3', '4', '8']
for example,
(['2', '3', '5'], ['1', '3', '4', '5'])
the above should yield the numbers 3 and 5
(['1', '2', '4'], ['1', '2'])
this should give out 1 , 2
(['2', '3', '5'], ['1', '2', '4'], ['2', '3'])
this, should give out 2, because 2 is contained in all 3 lists in the tuple. If there is no set it should just return an empty list
for i,e in enumerate(tup):
while index < len(tup):
print(tup[index], tup[index + 1])
index = index + 1
For now i have this, i am not sure how to go through the tup(Tuple) and extract each list to find the set of each 2 lists and iterate and compare with the rest of lists in the tuple
def intersect(lists):
return list(set.intersection(*map(set, lists)))
In [8]: t = (['2', '3', '5'], ['1', '3', '4', '5'])
In [9]: functools.reduce(lambda a,b: set.intersection(set(a), set(b)), t)
Out[9]: {'3', '5'}
Be consistent in return types. Don't return an empty string when you have an empty set.
That being said, I'd find the numbers like this:
>>> lsts = (['2', '3', '5'], ['1', '3', '4', '5'])
>>> set(lsts[0]).intersection(*lsts[1:])
set(['3', '5'])
>>>
>>> lsts = (['1', '2', '4'], ['1', '2'])
>>> set(lsts[0]).intersection(*lsts[1:])
set(['1', '2'])
>>>
>>> lsts = (['2', '3', '5'], ['1', '2', '4'], ['2', '3'])
>>> set(lsts[0]).intersection(*lsts[1:])
set(['2'])
The function for that would be:
>>> def common(lsts):
... return set() if not lsts else set(lsts[0]).intersection(*lsts[1:])
Simple as that: python has a set type, so just
sets = [set(l) for l in (['2', '3', '5'], ['1', '3', '4', '5']) ]
common_elements = reduce(lambda a,b: a & b, sets)
I have an array,
list = [['a', '2', '7'], ['b', '2', '9'],['a', '1', '4'],['c', '6', '1'],['b', '9', '9'],['a', '3', '2'],['c', '1', '5'],['b', '3', '7']]
I can write:
aList = [[row [1], row [2]] for row in list if row [0] == "a"]
bList = [[row [1], row [2]] for row in list if row [0] == "b"]
cList = [[row [1], row [2]] for row in list if row [0] == "c"]
to make a sub-array of second and third elements that has a specific first element i.e. ‘a’ , ‘b’ or ‘c’.
But I want to know what is the way to write one code that will do the work for all the first element.
Use a dictionary with the first item as key and rest of the items as values. collections.defaultdict will make this task a little easier for you, you can do this using a plain dict as well:
>>> from collections import defaultdict
>>> lst = [['a', '2', '7'], ['b', '2', '9'],['a', '1', '4'],['c', '6', '1'],['b', '9', '9'],['a', '3', '2'],['c', '1', '5'],['b', '3', '7']]
>>> d = defaultdict(list)
>>> for x in lst:
d[x[0]].append(x[1:])
#For plain dict this is going to be:
#d.setdefault(x[0], []).append(x[1:])
>>> d['a']
[['2', '7'], ['1', '4'], ['3', '2']]
>>> d['b']
[['2', '9'], ['9', '9'], ['3', '7']]
>>> d['c']
[['6', '1'], ['1', '5']]
import operator
L = [['a', '2', '7'], ['b', '2', '9'],['a', '1', '4'],['c', '6', '1'],['b', '9', '9'],['a', '3', '2'],['c', '1', '5'],['b', '3', '7']]
lists = {'a':[], 'b':[], 'c':[]}
g = operator.itemgetter(1,2)
for t in L:
lists[t[0]].append(g(t))
print('aList:', lists['a'])
print('bList:', lists['b'])
print('cList:', lists['c'])
Output:
aList: [('2', '7'), ('1', '4'), ('3', '2')]
bList: [('2', '9'), ('9', '9'), ('3', '7')]
cList: [('6', '1'), ('1', '5')]
Dictionary can do this work for you.
dict_list = {}
for row in list:
dict_list.setdefault(row[0],[])
dict_list[row[0]].append(row[1:])
setdefault will set the value as empty list [] if the key doesn't exist.
Output:
>>>dict_list
{'a': [['2', '7'], ['1', '4'], ['3', '2']],
'c': [['6', '1'], ['1', '5']],
'b': [['2', '9'], ['9', '9'], ['3', '7']]}