Empty list index error - python

I wrote the following two functions:
def place_walls(level):
wall_cords = level[2].split("\n")
for cord in wall_cords:
process_coordinate(cord)
def process_coordinate(coordinate):
cords = coordinate.split()
print cords[0]
Python returns a list index out of range error. If I print the cords variable without an index it prints all the cords in a list, however the last list is an empty list. Might that be the problem, how could that be solved?
The input level looks like this:
1 0
0 0=r=3 3
4 3
5 3
6 3
7 3
8 3
9 3
10 3
11 3
3 4

Assuming it is just the last, empty list you have a problem with: clearly, there is no 1st element to print in that case, so wrap it in an if statement (for example if len(cords)>0:; if the list is empty, do whatever is more appropriate for that circumstance.

Related

how can i print a range of numbers without a list in python?

for make in range(1, content+1):
print(make)
Result:
1
2
3
4
5
But i want them like this :
1 2 3 4 5 6 7
You need to modify the print command to tell it the separator to use with the "end" argument:
for make in range(1, content+1):
print(make,end=' ')

Nested for loops with if/else in python

simple situation,
I have the following: When I just have an if statement, it works correctly.
products = [1,2,3,4,5]
orders = [1,2,3,4,5]
for product in products:
for order in orders:
if product == order:
print("in list")
Results:
in list
in list
in list
in list
in list
However when adding an else it doesn't work correctly.
for product in products:
for order in orders:
if product == order:
print("in list")
else:
print("not in")
Results:
in list
not in
not in
not in
not in
not in
How can I fix it?
Any help is appreciated.
The set type is a better choice when you want to check if item is in a unique "list of item", e.g.
Lets consider the case where orders are non-unique and products are unique,
products = [1,2,3,4,5]
orders = set([1,2,3,4,5])
for p in products:
if p in orders:
print(f'product {p} in orders set')
else:
print(f'product {p} not in orders set')
Note: Here we use the f-string where you can print to see which p is in the order set.
Lets go back to the code in the original question, you have 2 lists and you want to iterate through the inner list for every outer list. Instead of calling it products/orders, lets call it outer/inner:
outer = [1,2,3,4,5]
inner = [6,7,8,9,0]
for o in outer:
for i in inner:
print(o, i)
[output]:
1 6
1 7
1 8
1 9
1 0
2 6
2 7
2 8
2 9
2 0
3 6
3 7
3 8
3 9
3 0
4 6
4 7
4 8
4 9
4 0
5 6
5 7
5 8
5 9
5 0
If you have a nested loop, for o in outer for i in inner, you will be iterating through all pairs of items in the outer list then the inner list.
Now lets go back to the if else part, if we are looping through the outer list then the inner list and if you only check on the outer list, with an if but not catching the else, you will not be seeing the results when it doesn't fall into the condition.
You can see this effect by adding the if-else after a print statement on every iteration, e.g.
outer = [1,2,3,4,5]
inner = [6,7,8,9,0]
for o in outer:
for i in inner:
print('printing always', o, i)
if o + 5 == i: # We are checking if outer+5=inner, i.e. 1+5= 6, 2+5=7, etc.
print('printing only when outer+5=inner', o, i)
[out]:
printing always 1 6
printing only when outer+5=inner 1 6
printing always 1 7
printing always 1 8
printing always 1 9
printing always 1 0
printing always 2 6
printing always 2 7
printing only when outer+5=inner 2 7
printing always 2 8
printing always 2 9
printing always 2 0
printing always 3 6
printing always 3 7
printing always 3 8
printing only when outer+5=inner 3 8
printing always 3 9
printing always 3 0
printing always 4 6
printing always 4 7
printing always 4 8
printing always 4 9
printing only when outer+5=inner 4 9
printing always 4 0
printing always 5 6
printing always 5 7
printing always 5 8
printing always 5 9
printing always 5 0
Now, we see that the normal loop print always prints, and if condition prints only when the condition is met.
To check when what is printed with an if and else, you can do something like:
outer = [1,2,3,4,5]
inner = [6,7,8,9,0]
for o in outer:
for i in inner:
print('printing always', o, i)
if o + 5 == i: # We are checking if outer+5=inner, i.e. 1+5= 6, 2+5=7, etc.
print('printing only when outer+5=inner', o, i)
else:
print('printing otherwise', o, i)
print('------------')
[output]:
printing always 1 6
printing only when outer+5=inner 1 6
------------
printing always 1 7
printing otherwise 1 7
------------
printing always 1 8
printing otherwise 1 8
------------
printing always 1 9
printing otherwise 1 9
------------
printing always 1 0
printing otherwise 1 0
------------
printing always 2 6
printing otherwise 2 6
------------
printing always 2 7
printing only when outer+5=inner 2 7
------------
printing always 2 8
printing otherwise 2 8
------------
printing always 2 9
printing otherwise 2 9
------------
printing always 2 0
printing otherwise 2 0
------------
printing always 3 6
printing otherwise 3 6
------------
printing always 3 7
printing otherwise 3 7
------------
printing always 3 8
printing only when outer+5=inner 3 8
------------
printing always 3 9
printing otherwise 3 9
------------
printing always 3 0
printing otherwise 3 0
------------
printing always 4 6
printing otherwise 4 6
------------
printing always 4 7
printing otherwise 4 7
------------
printing always 4 8
printing otherwise 4 8
------------
printing always 4 9
printing only when outer+5=inner 4 9
------------
printing always 4 0
printing otherwise 4 0
------------
printing always 5 6
printing otherwise 5 6
------------
printing always 5 7
printing otherwise 5 7
------------
printing always 5 8
printing otherwise 5 8
------------
printing always 5 9
printing otherwise 5 9
------------
printing always 5 0
printing otherwise 5 0
------------
This is working correctly.
One the first loop its comparing 1 to 1,2,3,4,5 then 2 to 1,2,3,4,5.
So because the if statement is true for at least one item in the loop, it will print every time its true. You don't have an else condition so every time it is not true, it doesn't do anything. The full output would be:
in list
not in
not in
not in
not in
not in
in list
not in
not in
not in
not in
not in
in list
not in
not in
not in
not in
not in
in list
not in
not in
not in
not in
not in
in list
In the second code, the total print statement executed will be 25 ( len(products) * len(orders) ).
You'll still get 5 "in list" in output, because when if statement result false, it'll go to else statement and print "not in".

reading a file that is detected as being one column

I have a file full of numbers in the form;
010101228522 0 31010 3 3 7 7 43 0 2 4 4 2 2 3 3 20.00 89165.30
01010222852313 3 0 0 7 31027 63 5 2 0 0 3 2 4 12 40.10 94170.20
0101032285242337232323 7 710153 9 22 9 9 9 3 3 4 80.52 88164.20
0101042285252313302330302323197 9 5 15 9 15 15 9 9 110.63 98168.80
01010522852617 7 7 3 7 31330 87 6 3 3 2 3 2 5 15 50.21110170.50
...
...
I am trying to read this file but I am not sure how to go about it, when I use the built in function open and loadtxt from numpy and i even tried converting to pandas but the file is read as one column, that is, its shape is (364 x 1) but I want it to separate the numbers to columns and the blank spaces to be replaced by zeros, any help would be appreciated. NOTE, some places there are two spaces following each other
If the columns content type is a string have you tried using str.split() This will turn the string into an array, then you have each number split up by each gap. You could then use a for loop for the amount of objects in the mentioned array to create a table out of it, not quite sure this has answered the question, sorry if not.
str.split():
So I finally solved my problem, I actually had to strip the lines and then read each "letter" from the line, in my case I am picking individual numbers from the stripped line and then appending them to an array. Here is the code for my solution;
arr = []
with open('Kp2001', 'r') as f:
for ii, line in enumerate(f):
arr.append([]) #Creates an n-d array
cnt = line.strip() #Strip the lines
for letter in cnt: #Get each 'letter' from the line, in my case it's the individual numbers
arr[ii].append(letter) #Append them individually so python does not read them as one string
df = pd.DataFrame(arr) #Then converting to DataFrame gives proper columns and actually keeps the spaces to their respectful columns
df2 = df.replace(' ', 0) #Replace the spaces with what you will

Finding the most frequent items in a dataset

I am working with a big dataset and thus I only want to use the items that are most frequent.
Simple example of a dataset:
1 2 3 4 5 6 7
1 2
3 4 5
4 5
4
8 9 10 11 12 13 14
15 16 17 18 19 20
4 has 4 occurrences,
1 has 2 occurrences,
2 has 2 occurrences,
5 has 2 occurrences,
I want to be able to generate a new dataset just with the most frequent items, in this case the 4 most common:
The wanted result:
1 2 3 4 5
1 2
3 4 5
4 5
4
I am finding the first 50 most common items, but I am failing to print them out in a correct way. (my output is resulting in the same dataset)
Here is my code:
from collections import Counter
with open('dataset.dat', 'r') as f:
lines = []
for line in f:
lines.append(line.split())
c = Counter(sum(lines, []))
p = c.most_common(50);
with open('dataset-mostcommon.txt', 'w') as output:
..............
Can someone please help me on how I can achieve it?
You have to iterate again the dataset and, for each line, show only those who are int the most common data set.
If the input lines are sorted, you may just do a set intersection and print those in sorted order. If it is not, iterate your line data and check each item
for line in dataset:
for element in line.split()
if element in most_common_elements:
print(element, end=' ')
print()
PS: For Python 2, add from __future__ import print_function on top of your script
According to the documentation, c.most-common returns a list of tuples, you can get the desired output as follow:
with open('dataset-mostcommon.txt', 'w') as output:
for item, occurence in p:
output.writelines("%d has %d occurrences,\n"%(item, occurence))

How to iterate through an intersection properly

I am trying to iterate through a series of intersections, where each iteration is the intersection of a new set of rows. I have code that looks somewhat like the following:
for liness in range(len(NNCatelogue)):
for iii in [iii for iii, y in enumerate(NNCatelogue[iii]) if y in set(NNCatelogue[liness]).intersection(catid)]:
print iii, y
NNCatelogue is essentially a 1268 X 12 matrix, and each new iteration of liness calls a new row. If I simply put in the row number that I want (ie: 0, 1, 2...) then I get the expected output (without the for loop in front). The code that is written above gives the following output:
10 C-18-1064
4 C-18-1122
4 C-18-1122
5 C-18-1122
5 C-18-1122
7 C-18-1122
8 C-18-1122
9 C-18-1122
10 C-18-1122
11 C-18-1122
6 C-18-1122
...
The expected output should be:
0 C-18-1
1 C-18-259
2 C-18-303
3 C-18-304
4 C-18-309
5 C-18-324
6 C-18-335
7 C-18-351
8 C-18-372
9 C-18-373
10 C-18-518
11 C-18-8
Any idea where I might be going wrong? Any help is greatly appreciated!
UPDATE:
I tried a variation of one of the answers, and while it is closer to what I am expecting, it isn't quite there. Here is what I tried:
counter = 0
for row in NNCatelogue:
for value in row:
if value in set(NNCatelogue[counter]).intersection(catid):
print counter, value
counter += 1
The resultant output is:
0 C-18-1
1 C-18-324
2 C-18-351
3 C-18-4
4 C-18-5
5 C-18-6
6 C-18-7
7 C-18-8
8 C-18-9
9 C-18-10
10 C-18-11
11 C-18-12
12 C-18-13
...
So some of the intersections are correct, though it isn't my desired output... Any ideas from here?
You use iii too often. I cannot even imagine what's exactly going on if you execute this code. Just give your variables useful speaking names and your problem is probably solved.
As I understand what you need:
counter = 0
for row in NNCatelogue:
for value in row:
if value in catid:
print counter, value
counter += 1
It appears that the intersection offers a non-numeric sort... Do you get the proper set (just the wrong permutation)?

Categories

Resources