Swap an item in list of list in python? - python

Given the list puzzle above, I need to be able to swap the position of X to left, right, top or bottom. The question is, how do I swap it with the item beside or in the other list in the list puzzle?
puzzle = [[' 1', ' 2', ' 3', ' 4'],
[' 5', ' 6', ' 7', ' 8'],
[' 9', '10', '11', '12'],
['13', '14', '15', ' X']]

#generic swap puzzle[a][b] with puzzle[c][d]
puzzle[a][b], puzzle[c][d] = puzzle[c][d], puzzle[a][b]

Related

Working with nested loops in python by keeping the inner list element as it is

I have a nested loop that follows as below
arr = [[' item 1 ', 'item 2 ', 'item 3'], ['item 4 ', 'item 5', 'item 6'], ['item 7 ', 'item 8', 'item 9' ]]
I am trying to loop through the arr with 2 for loops to get rid of (strip) the spaces around each item in the inner loop. But when I use the following code, although I can get rid of the spaces, the final result only forms a combined list without the inner list elements intact.
clean_arr = []
for i in arr:
for j in i:
clean_arr.append(j.strip(' '))
The result I get is a single list without any inner lists/nested lists. But what I want is to keep the exact nested structure.
How can I achieve the result? Could you please put some discussion as well. Thanks
Try a list comprehension as follows:
clean_arr = [[y.strip() for y in x] for x in arr]
print(clean_arr)
Output:
[['item 1', 'item 2', 'item 3'], ['item 4', 'item 5', 'item 6'], ['item 7', 'item 8', 'item 9']]
If you want to use a for loop, try the below code:
clean_arr = []
for i in arr:
l = []
for j in i:
l.append(j.strip())
clean_arr.append(l)

Give the number and fill the xth (x is the number) item in a list with '1',keep others empty

for example, I have a list of data like this:
['81', '88', '99', '124', '144', '145', '216', '223', '225', '227', '231', '232', '233', '236', '238', '239', '240', '241', '242', '244', '245', '246', '247', '248', '249', '250', '251', '253', '254', '256', '257', '259', '260', '261', '264', '265', '266', '267', '268', '269', '270', '271', '272', '273', '274', '275', '276', '278', '279', '280', '281', '284', '285', '288', '296', '299', '304']
and I created a list, which contains 365 of ' ' by using julianList=[" "] *365
Now, what I need to do is change the xth(x is number) of item in juLianList into '1'
I use the following code
julianList=[" "] *365
EjulianList=list(enumerate(julianList))
## print(EjulianList)
print(julianList[2])
for i in range(len(julian)):
for j in range(len(EjulianList)):
if julian[i]==EjulianList[j][0]:
julianList[j]='1'
print(julianList)
but still get a list with 365 ' '
like
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
what's wrong with it?
There are two (obvious) ways to do it.
The first, initializes the list and corrects some of its entries depending on the contents of data list.
data = ['1', '7', '8']
julianList = [" "] * 10
for i in map(int, data):
julianList[i] = '1'
print(julianList) # -> [' ', '1', ' ', ' ', ' ', ' ', ' ', '1', '1', ' ']
The second, is a list comprehension that creates the correct input as the list is created.
data = ['1', '7', '8']
# optionally to speed up the membership tests do : data = set(data)
julianList = ['1' if str(i) in data else ' ' for i, _ in enumerate(range(10))]
print(julianList) # -> [' ', '1', ' ', ' ', ' ', ' ', ' ', '1', '1', ' ']
Note that I scaled the problem down for visualization purposes.
The first method is preferable in your case, because of the costly membership tests required by the second approach. To improve on those, you can cast data into set before running the list-comprehension by doing data = set(data).
It would however be even better if you would just create a dictionary that contains your '1's and just use .get() to get the ' 's tookudos #JonClemens.
julianDict = dict.fromkeys(map(int, data), '1')
with the dict in place, you can do:
print(julianDict.get(7, ' ')) # -> '1'
print(julianDict.get(3, ' ')) # -> ' '
This 3rd option is by far the most efficient but does not provide you with a list. You can use it to built one though if you really need it.
julianInsistsOnTheList = [julianDict.get(x, ' ') for x in range(365)]
enumerate generates tuples, where the first is a number, in julian the elements are strings, therefore if julian[i] == EjulianList[j][0] is never true.
Simply, convert your numbers into int.
By the way, lists in Python are 0-based, so you have to shift the day's by one:
with open('data.csv') as inputfile:
reader = csv.reader(inputfile)
julian = [int(c) for c in next(reader)]
julianList = [" "] * 365
for day in julian:
julianList[day - 1] = "1"
In fact
julianList = ['1' if str(i) in julian else ' ' for i, x in enumerate(range(365))]
in the comment is what I want

How to print part of item in a list? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a list that looks like this:
['Blake 4', 'Bolt 1', 'De Grasse 3', 'Gatlin 2', 'Simbine 5', 'Youssef Meite 6']
I am trying to print this:
Blake
Bolt
De Grasse
Gatlin
Simbine
Youssef Meite
How do I go about writing a list comprehension that handles this scenario? I tried using split and indexing but nothing I have used has worked.
Assuming all the values keep that pattern, split and join back, ignoring last value in splitted array:
l = ['Blake 4', 'Bolt 1', 'De Grasse 3', 'Gatlin 2', 'Simbine 5', 'Youssef Meite 6']
for x in l:
print(' '.join(x.split()[:-1]))
Otherwise, use regex to eliminate numerals:
import re
l = ['Blake 4', 'Bolt 1', 'De Grasse 3', 'Gatlin 2', 'Simbine 5', 'Youssef Meite 6']
for x in l:
print(re.sub(' \d+', '', x))
list comprehension is useless to print stuff (or any operations where you don't need the return value).
In your case, you could use str.rpartition in a loop to print only the left hand of the rightmost space found in the string:
l =['Blake 4', 'Bolt 1', 'De Grasse 3', 'Gatlin 2', 'Simbine 5', 'Youssef Meite 6']
for s in l:
print(s.rpartition(" ")[0])
Just stripping the last digit off the list would be a good usage of listcomp:
newl = [s.rpartition(" ")[0] for s in l]
Try this:
l = ['Blake 4', 'Bolt 1', 'De Grasse 3', 'Gatlin 2', 'Simbine 5', 'Youssef Meite 6']
for i in l:
print(i[:-2])
Indexing is sufficient for solving your problem.
Based on #Jean-François 's comment, if you are trying to remove all the characters before the last space, you can do this instead:
l = ['Blake 4', 'Bolt 1', 'De Grasse 3', 'Gatlin 2', 'Simbine 5', 'Youssef Meite 6']
for i in l:
print(i[:-i[::-1].index(' ')-1])

sorting using python for complex strings [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have an array that contains numbers and characters, e.g. ['A 3', 'C 1', 'B 2'], and I want to sort it using the numbers in each element.
I tried the below code but it did not work
def getKey(item):
item.split(' ')
return item[1]
x = ['A 3', 'C 1', 'B 2']
print sorted(x, key=getKey(x))
To be safe, I'd recommend you to strip everything but the digits.
>>> import re
>>> x = ['A 3', 'C 1', 'B 2', 'E']
>>> print sorted(x, key=lambda n: int(re.sub(r'\D', '', n) or 0))
['E', 'C 1', 'B 2', 'A 3']
With your method;
def getKey(item):
return int(re.sub(r'\D', '', item) or 0)
>>> print sorted(x, key=getKey)
['E', 'C 1', 'B 2', 'A 3']
What you have, plus comments to what's not working :P
def getKey(item):
item.split(' ') #without assigning to anything? This doesn't change item.
#Also, split() splits by whitespace naturally.
return item[1] #returns a string, which will not sort correctly
x = ['A 3', 'C 1', 'B 2']
print sorted(x, key=getKey(x)) #you are assign key to the result of getKey(x), which is nonsensical.
What it should be
print sorted(x, key=lambda i: int(i.split()[1]))
This is one way to do it:
>>> x = ['A 3', 'C 1', 'B 2']
>>> y = [i[::-1] for i in sorted(x)]
>>> y.sort()
>>> y = [i[::-1] for i in y]
>>> y
['C 1', 'B 2', 'A 3']
>>>

Heapsort not working in Python for list of strings using heapq module

I was reading the python 2.7 documentation when I came across the heapq module. I was interested in the heapify() and the heappop() methods. So, I decided to write a simple heapsort program for integers:
from heapq import heapify, heappop
user_input = raw_input("Enter numbers to be sorted: ")
data = map (int, user_input.split(","))
new_data = []
for i in range(len(data)):
heapify(data)
new_data.append(heappop(data))
print new_data
This worked like a charm.
To make it more interesting, I thought I would take away the integer conversion and leave it as a string. Logically, it should make no difference and the code should work as it did for integers:
from heapq import heapify, heappop
user_input = raw_input("Enter numbers to be sorted: ")
data = user_input.split(",")
new_data = []
for i in range(len(data)):
heapify(data)
print data
new_data.append(heappop(data))
print new_data
Note: I added a print statement in the for loop to see the heapified list.
Here's the output when I ran the script:
`$ python heapsort.py
Enter numbers to be sorted: 4, 3, 1, 9, 6, 2
[' 1', ' 3', ' 2', ' 9', ' 6', '4']
[' 2', ' 3', '4', ' 9', ' 6']
[' 3', ' 6', '4', ' 9']
[' 6', ' 9', '4']
[' 9', '4']
['4']
[' 1', ' 2', ' 3', ' 6', ' 9', '4']`
The reasoning I applied was that since the strings are being compared, the tree should be the same if they were numbers. As is evident, the heapify didn't work correctly after the third iteration. Could someone help me figure out if I am missing something here? I'm running Python 2.4.5 on RedHat 3.4.6-9.
Thanks,
VSN
You should strip the spaces. They are the reason for this strange sorting. Sorting of strings is done character by character with ASCII codes.
So try:
from heapq import heapify, heappop
user_input = raw_input("Enter numbers to be sorted: ")
data = user_input.split(",")
data = map(str.strip, data)
new_data = []
heapify(data)
for i in range(len(data)):
print(data)
new_data.append(heappop(data))
print(new_data)
Sorting
This question is rather about sorting than about heapq. And sorting itself in this context is essentially only about how < and <= works.
Sorting numbers works intuitively, but strings are different. Usually strings are sorted character by character by the bitpattern they use. This is the reason for the following behaviour
>>> sorted("abcABC")
['A', 'B', 'C', 'a', 'b', 'c']
The ASCII code for A is 65 and for a it's 97 (see ASCII Table).
The sorting is done character by character. If a string a is a prefix of another string b, it's always a < b.
>>> sorted(["123", "1", "2", "3", "12", "15", "20"])
['1', '12', '123', '15', '2', '20', '3']
What you want is called "natural sorting". See natsort for that.

Categories

Resources