Split list on smaller lists with equal elements - python

In my list "A" i have got numbers and ' ', so I want to make a list of list named e.g "b", every list should have nine number (if it possible), no matter how much it have ' '.
Any idea how to do this?
A = ['1', '3', '4', '5', '7', '8', '9', ' ', '13', '16', '3', ' ', '5', '17']
B = [ ['1', '3, '4', '5', '7', '8', '9', ' ', '13', '16'], ['3', ' ', '5', '17'] ]

This will help you:
>>> a = ['1', '3', '4', '5', '7', '8', '9', ' ', '13', '16', '3', ' ', '5', '17']
>>> b=[a[i:i+9] for i in xrange(0,len(a),9)]
>>> b
[['1', '3', '4', '5', '7', '8', '9', ' ', '13'], ['16', '3', ' ', '5', '17']]
>>>

This can be done with two nested while loops:
>>> A = ['1', '3', '4', '5', '7', '8', '9', ' ', '13', '16', '3', ' ', '5', '17']
>>> B = []
>>> while A:
... L = []
... c = 0
... while A and c < 9:
... L.append(A.pop(0))
... if L[-1].isdigit():
... c += 1
... B.append(L)
...
>>> B
[['1', '3', '4', '5', '7', '8', '9', ' ', '13', '16'], ['3', ' ', '5', '17']]
The outer one loops while A is not empty and the inner one while A is not empty and the number of digit only strings appended to the current sub-list is less than 9. The counter is only incremented after a string consisting of only digits is found.

It would be worth your time to get deep into list comprehensions
And there is no xrange in Python 3.x or rather range (in 3.x) does exactly what xrange did in Python 2.x.
A = ['1', '3', '4', '5', '7', '8', '9', ' ', '13', '16', '3', ' ', '5', '17']
B = [i for i in A[0:9]] #is cleaner.
Though I'm not sure exactly what your goal is. Do you want the second list (the remainder list as I'm thinking of it) to be in the same variable? So if you had 28 elements in your list you'd want three lists of 9 and one list of 1?

This is a bit dirty solution but I think you might need to check isdigit part and pop.
def take(lst, n):
if not lst:
return ValueError("Empty list, please check the list.")
items = list(lst)
new_list = []
count = 0
while items:
item = items.pop(0)
new_list.append(item)
if item.isdigit():
count += 1
if count >= n:
yield new_list
new_list = []
count = 0
if new_list:
yield new_list
A = ['1', '3', '4', '5', '7', '8', '9', ' ', '13', '16', '3', ' ', '5', '17']
B = [ii for ii in take(A, 9)]
#[['1', '3', '4', '5', '7', '8', '9', ' ', '13', '16'], ['3', ' ', '5', '17']]
Check the following:
https://docs.python.org/2/library/stdtypes.html#str.isdigit

Related

how can i split string with no blank?

input = '1+2++3+++4++5+6+7++8+9++10'
string = input.split('+')
print(string)
when we run this code the output is ['1', '2', '', '3', '', '', '4', '', '5', '6', '7', '', '8', '9', '', '10']
But i want to split the string with no blank like ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
Is there any function or method to remove blanks without using for loop like
for i in string:
if i == '':
string.remove(i)
Generate a list based on the output of split, and only include the elements which are not None
You can achieve this in multiple ways. The cleanest way here would be to use regex.
Regex:
import re
re.split('\++', inp)
#['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
List Comprehension:
inp = '1+2++3+++4++5+6+7++8+9++10'
[s for s in inp.split('+') if s]
#['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
Loop & Append:
result = []
for s in inp.split('+'):
if s:
result.append(s)
result
#['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
Simplest way:
customStr="1+2++3+++4++5+6+7++8+9++10"
list( filter( lambda x : x!="" ,customStr.split("+") ) )

Python: How to convert a set of strings that contains commas represented as an element of a list to a sub-list?

I have a list that contains a set of strings like this:
list = ['235,ACCESS,19841136,22564960,4291500,20,527434,566876','046,ALLOWED,24737321,27863065,1086500,3,14208500,14254500']
I'm trying to make the elements of the list a sublist but without splitting the string.
I tried new_list = list(map(list, list)). This is the result taking as reference the first element of the list:
print(new_list[0]):
[['2', '3', '5', ',', 'A', 'C', 'C', 'E', 'S',',','1', '9', '8', '4', '1', '1', '3', '6', ',', '2', '2', '5', '6', '4', '9', '6', '0', ',', '4', '2', '9', '1', '5', '0', '0', ',', '2', '0', ',', '5', '2', '7', '4', '3', '4', ',', '5', '6', '6', '8', '7', '6']]
I would like this output:
print(new_list[0]):
[[235,'ACCESS',19841136,22564960,4291500,20,527434,566876]]
Thanks in advance for your help!
You can try split() with delimiter , like this -
new_list = [i.split(',') for i in list]
print (new_list[0])
Output:
['235', 'ACCESS', '19841136', '22564960', '4291500', '20', '527434', '566876']
One thing is that here the numbers are also represented as string. If you want integers instead you can use isdigit() method like this -
new_list = [[int(e) if e.isdigit() else e for e in i.split(',') ]for i in list]
print(new_list[0])
Output:
[235, 'ACCESS', 19841136, 22564960, 4291500, 20, 527434, 566876]
Also, please try to avoid naming your list list

Python - iterating over nested loop

First off i am certain that such a basic thing has been asked before, but i could not find a post about it.
I have this piece of example data:
'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'],
'192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'],
'192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6'],
'192.168.244.230': ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
And i want to print out every line (each line is one dictionary key-value pair) that has a list-value whose list contains any amount of items that is not 0 (in this case, every line except the 4th)
I just cant seem to figure out this seemingly simple thing - what i tried before was those two things:
for i in d.keys():
if "0" not in d[i]:
print(i, d[i])
This one shows only lists that do not contain 0 AT ALL - so the third line would not be shown, even though it contains non-0 values
for i in d.keys():
for j in d[i]:
if j is not "0":
print(i, d[i])
This one DOES show me what i want, but as you can tell, it prints every result way too often - one print for every list value that is not 0.
You can simply iterate over like
def all_zero(arr):
for i in arr:
if i != 0:
return False
else:
return True
You can call it on all the lists one by one.
Use a dictionary-comprehension:
d = {'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'],
'192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'],
'192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6'],
'192.168.244.230': ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']}
result = {k: v for k, v in d.items() if not all(x == '0' for x in v)}
# {'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'],
# '192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'],
# '192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6']}
The above code generates a new dictionary which omits all items where values are all zeros.
Now that you have a dictionary, you can easily do an iteration like so:
for k, v in result.items():
print(k, v)
Your bug is basically just a missing break:
for i in d.keys():
for j in d[i]:
if j != "0":
print(i, d[i])
break
However, for conciseness I would recommend you check out the any() function, which does exactly what you want: Return true if any of the elements of the iterable are true (when cast to booleans).
Eg:
for i in d.keys():
if any(j != "0" for j in d[i]):
print(i, d[i])
(The j is not "0" generator is only necessary because you have string values. For an int array, any(d[i]) would work.)
Even more "Pythonic" would be removing the need for a dictionary lookup:
for i, d_i in d.items():
if any(j != "0" for j in d_i):
print(i, d_i)
I like the other answers but I feel like you can get away with something like this as well:
for i in d.keys():
#If there are as many zeroes as there are elements in the list...
if d[i].count(0) == len(d[i]):
#...You might as well skip it :)
continue
print(d[i])
for i in d.keys():
all_zero = True
for j in d[i]:
if j is not "0":
all_zero = False
break
if not all_zero:
print(i, d[i])
This may work for almost every language :)
Have a look at how I could accomplish this.
d = {
'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'],
'192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'],
'192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6'],
'192.168.244.230': ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
}
for key in d.keys():
if all( item == '0' for item in d[key]):
pass
else:
print(key, d[key])
You should use all in this case, consider following example:
digits = ['0', '2', '0', '4', '7', '5', '0', '3', '2', '6']
zeros = ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
print(all([k=='0' for k in digits])) #gives False
print(all([k=='0' for k in zeros])) #gives True
Please remember to deliver [k=='0' for k in ...] to all, as delivering list directly would give True for both digits and zeros, as both contain at least one non-empty str (str of length 1 or greater).

[Optimizing]Appending Numbers from a list with delimeters

So I am working on a piece of code, and I am trying to find out the most efficient and fastest method to split the list into the numbers I need.
Here is the code that I am using:
eq=[' ', '1', '.', '3', '3', '5', '9', '2', '0', 'e', '0', '6', ' ', '4', '.', '0', '2', '0', '7', '4', '9', 'e', '0', '1']
coeff=[]
i=0
while i < len(eq)-1:
temp=""
if eq[i]==' ':
for x in range(i+1,len(eq)):
if eq[x]== ' ':
break
else:
temp+=eq[x]
coeff.append(float(temp))
i=x
print coeff
This does give me the desired result, which is [1335920.0, 40.20749], but I am wondering if there is a better way to do this.
Please note that the numbers are coming from R, and as such, I cannot guarantee they will be in exactly the same format all the time, so slicing the list is not an option.
In [1]: eq = [' ', '1', '.', '3', '3', '5', '9', '2', '0', 'e', '0', '6', ' ', '4', '.', '0', '2', '0', '7', '4', '9', 'e', '0', '1']
In [2]: map(float, ''.join(eq).strip().split(' '))
Out[2]: [1335920.0, 40.20749]
Explanation:
''.join(eq) joins the strings from the list
strip() removes the leading and trailing whitespace
split(' ') splits the string by a single space
map applies float to each string in the list

Delete blank entries in CSV file Python

I need to read in a CSV file, from Excel, whose rows may be an arbitrary length.
The problem is the python retains these blank entries, but need to delete them for a future algorithm. Below is the output, I don't want the blank entries.
['5', '1', '5', '10', '4', '']
['3', '1', '5', '10', '2', '']
['6', '1', '5', '10', '5', '2']
['9', '10', '5', '10', '7', '']
['8', '5', '5', '10', '7', '']
['1', '1', '5', '10', '', '']
['2', '1', '5', '10', '1', '']
['7', '1', '5', '10', '6', '4']
['4', '1', '5', '10', '3', '1']
Here's a list comprehension integrated with the csv library:
import csv
with open('input.csv') as in_file:
reader = csv.reader(in_file)
result = [[item for item in row if item != ''] for row in reader]
print result
This is about as verbose a function as I could write to do what you want. There are certainly slicker ways.
def remove_blanks(a_list):
new_list = []
for item in a_list:
if item != "":
new_list.append(item)
return new_list
List comprehension version:
a = ['5', '1', '5', '10', '4', '']
[x for x in a if x != '']
Out[19]: ['5', '1', '5', '10', '4']
You may be better served by filtering at the csv read step instead.

Categories

Resources