I have a dictionary say : my_map_dict which looks something like below:
{2: [['1', '2', '4', '4', '0', '2', '0', '0.67'], ['5', '6', '3', '8', '0', '2', '1', '0.67'], ['6', '9', '4', '9', '0', '2', '2', '0.67'], ['4', '3', '6', '9', '0', '2', '3', '1.00']], 3: [['4', '6', '6', '1', '0', '3', '0', '0.67'], ['5', '9', '4', '8', '0', '3', '1', '0.67']], 4: [['1', '9', '4', '9', '0', '4', '0', '0.67']]}
Where 2,3,4 are the keys of the dictionary and those lists are the values of that.
Now I want to generate a file from this say outputfile.txt which will take all the values of the dictionary and make that a CSV file which looks like below (desired output):
1,2,4,4,0,2,0,0.67
5,6,3,8,0,2,1,0.67
6,9,4,9,0,2,2,0.67
4,3,6,9,0,2,3,1.00
4,6,6,1,0,3,0,0.67
5,9,4,8,0,3,1,0.67
1,9,4,9,0,4,0,0.67
How can I do it?
Flatten the values of your dictionary to a single list of lists, and use the csv module to write to file:
import csv
with open("output.csv","w",newline="") as f:
writer = csv.writer(f)
writer.writerows([item for sublist in d.values() for item in sublist])
output.csv
1,2,4,4,0,2,0,0.67
5,6,3,8,0,2,1,0.67
6,9,4,9,0,2,2,0.67
4,3,6,9,0,2,3,1.00
4,6,6,1,0,3,0,0.67
5,9,4,8,0,3,1,0.67
1,9,4,9,0,4,0,0.67
Related
I am fairly new to coding, and I need to put columns from a CSV file into a list. I cannot use any libraries like Pandas. This is the current code I have, but it is taking each character individually. What do I need to change so it takes the entire word?
def readfile(f):
with open(f) as csv_file:
csv_reader= csv.reader(csv_file, delimiter= ',')
for i in csv_reader:
newlist= list(i[1])
print(newlist)
This is an example of the output created.
['P', 'O', 'P', 'U', 'L', 'A', 'T', 'I', 'O', 'N']
['5', '2', '2', ',', '8', '1', '8']
['1', '5', '5', ',', '6', '5', '6']
['9', '6', '6', ',', '7', '0', '9']
['7', '7', '3', ',', '8', '8', '7']
['8', ',', '4', '4', '7', ',', '6', '0', '9']
['1', '4', ',', '4', '8', '4', ',', '2', '4', '2']
['1', ',', '3', '6', '4', ',', '4', '0', '0']
['1', ',', '1', '7', '1', ',', '0', '2', '7']
['4', ',', '3', '5', '0', ',', '9', '0', '1']
['5', ',', '0', '4', '6', ',', '7', '8', '0']
['4', '0', ',', '6', '0', '1']
['4', '4', ',', '9', '0', '9']
['3', '8', ',', '6', '6', '6']
I need it to all be in one list, like [522,818 , 155,656 , etc]
Assuming you would like to concatenate the rows from a csv containing a list in each row, such that an input csv looking like:
population
1,2
3,4
would print -> [1,2,3,4]
You can use the extend function on the python list builtin.
Here's how it would look:
import csv
with open('example.csv') as ff:
reader = csv.reader(ff)
reader.next() # skip the header that you arent using
concat_output = []
for row in reader:
concat_output.extend(row)
print(concat_output)
Perhaps this is what you are looking for:
>>>''.join(['5', '2', '2', ',', '8', '1', '8'])
'522,818'
I just found this earlier thread which provides more background/terminology: How to concatenate items in a list to a single string?.
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).
I have a list of lists of strings:
listBefore = [['4', '5', '1', '1'],
['4', '6', '1', '1'],
['4', '7', '8', '1'],
['1', '2', '1', '1'],
['2', '3', '1', '1'],
['7', '8', '1', '1'],
['7', '9', '1', '1'],
['2', '4', '3', '1']]
and I would like to add a counter/index in the middle of each list so that the list looks like:
listAfter = [['4', '5', '1', '1', '1'],
['4', '6', '2', '1', '1'],
['4', '7', '3', '8', '1'],
['1', '2', '4', '1', '1'],
['2', '3', '5', '1', '1'],
['7', '8', '6', '1', '1'],
['7', '9', '7', '1', '1'],
['2', '4', '8', '3', '1']]
What would be the easiest way to do so? I could probably loop over the lists and add the index, but is there a cleaner way to do so?
Cheers,
Kate
Edit:
The code I wrote works for me:
item = 1
for list in listBefore:
list.insert(2,str(item))
item = item + 1
print listBefore
I was wondering if there is another way to do so more efficiently or in one step.
Iterate over the parent list with enumerate() to get counter (used as i in the below example) along with list element. In the sublist, insert the i at the middle of sublist using list.insert(index, value) method.
Note: The value of counter i.e. i will be of int type, so you have to explicitly type cast it to str as str(i)before inserting. Below is the sample code:
for i, sub_list in enumerate(my_list, 1): # Here my_list is the list mentioned in question as 'listBefore'
sub_list.insert(len(sub_list)/2, str(i))
# Value of 'my_list'
# [['4', '5', '1', '1', '1'],
# ['4', '6', '2', '1', '1'],
# ['4', '7', '3', '8', '1'],
# ['1', '2', '4', '1', '1'],
# ['2', '3', '5', '1', '1'],
# ['7', '8', '6', '1', '1'],
# ['7', '9', '7', '1', '1'],
# ['2', '4', '8', '3', '1']]
You can perform this with a list comprehension
listAfter = [listBefore[i][:len(listBefore[i])/2] + [str(i+1)] + listBefore[i][len(listBefore[i])/2:] for i in range(len(listBefore))]
You should learn about enumerate, it lets you iterate over the list with two iterators - one (str_list in this case) holds the current item in the list, and the other (i`) holds it's index in the list.
for i,str_list in enumerate(listBefore):
listBefore[i] = str_list[:len(str_list)//2] + [str(i+1)] + str_list[len(str_list)//2:]
>>> data = [['4', '5', '1', '1'],
['4', '6', '1', '1'],
['4', '7', '8', '1'],
['1', '2', '1', '1'],
['2', '3', '1', '1'],
['7', '8', '1', '1'],
['7', '9', '1', '1'],
['2', '4', '3', '1']]
>>> print [row[:len(row)//2] + [str(i)] + row[len(row)//2:]
for i, row in enumerate(data, start=1)]
[['4', '5', '1', '1', '1'],
['4', '6', '2', '1', '1'],
['4', '7', '3', '8', '1'],
['1', '2', '4', '1', '1'],
['2', '3', '5', '1', '1'],
['7', '8', '6', '1', '1'],
['7', '9', '7', '1', '1'],
['2', '4', '8', '3', '1']]
I'm trying to draw histrogram based of my value
x = ['3', '1', '4', '1', '5', '9', '2', '6', '5', '3', '5',
'2', '3', '4', '5', '6', '4', '2', '0', '1', '9', '8',
'8', '8', '8', '8', '9', '3', '8', '0', '9', '5', '2',
'5', '7', '2', '0', '1', '0', '6', '5']
x_num = [int(i) for i in x]
key = '0123456789'
for i in key:
print(i," count =>",x.count(i))
plt.hist(x_num, bins=[0,1,2,3,4,5,6,7,8,9])
The last 2 numbers "8, 9" bin should have distribution count of 6 , 4
But in histogram it combine 8 and 9 and get value of 10 instead of separate them. Total number of bin should be 10 => but it only giving me graph of 9..
How could I separate them and break 8 and 9 ?
import matplotlib.pyplot as plt
x = ['3', '1', '4', '1', '5', '9', '2', '6', '5', '3', '5',
'2', '3', '4', '5', '6', '4', '2', '0', '1', '9', '8',
'8', '8', '8', '8', '9', '3', '8', '0', '9', '5', '2',
'5', '7', '2', '0', '1', '0', '6', '5']
x_num = [int(i) for i in x]
key = '0123456789'
for i in key:
print(i, " count =>", x.count(i))
plt.hist(x_num, bins=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10])
plt.show()
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.