In the code below, I am trying to use len(list) to count the number of strings in an array in each of the tags variables from the while loop. When i did a sample list parameter on the bottom, list2, it printed 5 which works, but when i did it with my real data,it was counting the characters in the array, not the number of strings. I need help figuring out why that is and i am new to python so the simplest way possible please!
#!/usr/bin/python
import json
import csv
from pprint import pprint
with open('data.json') as data_file:
data = json.load(data_file)
#pprint(data)
# calc number of alert records in json file
x = len(data['alerts'])
count = 0
while (count < x):
tags = str(data['alerts'][count] ['tags']).replace("u\"","\"").replace("u\'","\'")
list = "[" + tags.strip('[]') + "]"
print list
print len(list)
count=count+1
list2 = ['redi', 'asd', 'rrr', 'www', 'qqq']
print len(list2)
Your list construction list = "[" + tags.strip('[]') + "]" creates a string, not a list. So yes, len works, it counts the characters in your string.
Your tags construction looks a bit off, you have a dictionary of data (data['alerts']) which you then convert to string, and strip of the '[]'. Why don't use just get the value itself?
Also list is a horrible name for your variable. This possible clashes with internal values.
list = "[" + tags.strip('[]') + "]"
print list
print len(list)
Ironically, list is a string, not a list. That's why calling len on it "was counting the characters in the array"
you need to make sure that your variable is a list rather than a str,
try:
print(type(yourList))
if it shows that it is a str, then try this:
len(list[yourList)
hope this answers your question
and when you want to establish a list variable, try this:
myList = []
for blah in blahblah:
myList.append(blah)
I think these definitely solved your problem, so I hope you noticed this part.
Related
I am trying to simply replace a list item with another item, except the new item has a space in it. When it replaces, it creates two list items when I only want one. How can I make it just one item in the list please?
Here is a minimal reproducible example:
import re
cont = "BECMG 2622/2700 32010KT CAVOK"
actual = "BECMG 2622"
sorted_fm_becmg = ['BECMG 262200', '272100']
line_to_print = 'BECMG 262200'
becmg = re.search(r'%s[/]\d\d\d\d' % re.escape(actual), cont).group()
new_becmg = "BECMG " + becmg[-4:] + "00" # i need to make this one list item when it replaces 'line_to_print'
sorted_fm_becmg = (' '.join(sorted_fm_becmg).replace(line_to_print, new_becmg)).split()
print(sorted_fm_becmg)
I need sorted_fm_becmg to look like this : ['BECMG 270000', '272100'].
I've tried making new_becmg a list item, I have tried removing the space in the string in new_becmg but I need the list item to have a space in it.
It is probably something simple but I can't get it. Thank you.
You can iterate through sorted_fm_becmg to replace each string individually instead:
sorted_fm_becmg = [b.replace(line_to_print, new_becmg) for b in sorted_fm_becmg]
I have written a short python script to search for urls with a http status code in a logfile. The script works as intended and counts how often an url is requested in combination with a certain http status code. The dictionary with the results is unsorted. Thats why i sorted the data afterwards using the values in the dictionary. This part of the script works as intended and i get a sorted list with the urls and the counter, The list looks like:
([('http://example1.com"', 1), ('http://example2.com"', 5), ('http://example3.com"', 10)])
I just want to make it better readable and print the list in rows.
http://example1.com 1
http://example2.com 5
http://example3.com 10
I started with python only two weeks ago and i cant find a solution. I tried several solutions i found here on stackoverflow but nothing works. My current solution prints all urls in seperate rows but does not show the count. I cant use comma as a seperator because i got some url with commas in my logfile. Im sorry for my bad english and the stupid question. Thank you in advance.
from operator import itemgetter
from collections import OrderedDict
d=dict()
with open("access.log", "r") as f:
for line in f:
line_split = line.split()
list = line_split[5], line_split[8]
url=line_split[8]
string='407'
if string in line_split[5]:
if url in d:
d[url]+=1
else:
d[url]=1
sorted_d = OrderedDict(sorted(d.items(), key=itemgetter(1)))
for element in sorted_d:
parts=element.split(') ')
print(parts)
for url, count in sorted_d.items():
print(f'{url} {count}')
Replace your last for loop with the above.
To explain: we unpack the url, count pairs in sorted_d in the for loop, and then use the an f-string to print the url and count separated by a space.
First if you're already importing from the collections library, why not import a Counter?
from collections import Counter
d=Counter()
with open("access.log", "r") as f:
for line in f:
line_split = line.split()
list = line_split[5], line_split[8]
url=line_split[8]
string='407'
if string in line_split[5]:
d[url] += 1
for key, value in d.most_common(): # or reversed(d.most_common())
print(f'{key} {value}')
There are many good tutorials on how to format strings in Python such as this
Here an example code how to print a dictionary. I set the width of the columns with the variables c1 and c2.
c1 = 34; c2 = 10
printstr = '\n|%s|%s|' % ('-'*c1, '-'*c2)
for key in sorted(d.keys()):
val_str = str(d[key])
printstr += '\n|%s|%s|' % (str(key).ljust(c1), val_str.rjust(c2))
printstr += '\n|%s|%s|\n\n' % ('-' * c1, '-' * c2)
print(printstr)
The string function ljust() creates a string of the length passed as an argument where the content of the string is left justified.
I need to write a list to a text file named accounts.txt in the following format:
kieranc,conyers,asdsd,pop
ethand,day,sadads,dubstep
However, it ends up like the following with brackets:
['kieranc', 'conyers', 'asdsd', 'pop\n']['ethand', 'day', 'sadads', 'dubstep']
Here is my code (accreplace is a list):
accreplace = [['kieranc', 'conyers', 'asdsd', 'pop\n'],['ethand', 'day', 'sadads', 'dubstep']]
acc = open("accounts.txt", "w")
for x in accreplace:
acc.write(str(x))
Since each element in accreplace is a list, str(x) doesn't help. It just adds quotes around it. To print the list in proper format use the code below:
for x in accreplace:
acc.write(",".join([str(l) for l in x]))
This will convert the list items into a string.
I am struggling with a small program in Python which aims at counting the occurrences of a specific set of characters in the lines of a text file.
As an example, if I want to count '!' and '#' from the following lines
hi!
hello#gmail.com
collection!
I'd expect the following output:
!;2
#;1
So far I got a functional code, but it's inefficient and does not use the potential that Python libraries have.
I have tried using collections.counter, with limited success. The efficiency blocker I found is that I couldn't select specific sets of characters on counter.update(), all the rest of the characters found were also counted. Then I would have to filter the characters I am not interested in, which adds another loop...
I also considered regular expressions, but I can't see an advantage in this case.
This is the functional code I have right now (the simplest idea I could imagine), which looks for special characters in file's lines. I'd like to see if someone can come up with a neater Python-specific idea:
def count_special_chars(filename):
special_chars = list('!"#$%&\'()*+,-./:;<=>?#[\\]^_`{|}~ ')
dict_count = dict(zip(special_chars, [0] * len(special_chars)))
with open(filename) as f:
for passw in f:
for c in passw:
if c in special_chars:
dict_count[c] += 1
return dict_count
thanks for checking
Why not count the whole file all together? You should avoid looping through string for each line of the file. Use string.count instead.
from pprint import pprint
# Better coding style: put constant out of the function
SPECIAL_CHARS = '!"#$%&\'()*+,-./:;<=>?#[\\]^_`{|}~ '
def count_special_chars(filename):
with open(filename) as f:
content = f.read()
return dict([(i, content.count(i)) for i in SPECIAL_CHARS])
pprint(count_special_chars('example.txt'))
example output:
{' ': 0,
'!': 2,
'.': 1,
'#': 1,
'[': 0,
'~': 0
# the remaining keys with a value of zero are ignored
...}
Eliminating the extra counts from collections.Counter is probably not significant either way, but if it bothers you, do it during the initial iteration:
from collections import Counter
special_chars = '''!"#$%&'()*+,-./:;<=>?#[\\]^_`{|}~ '''
found_chars = [c for c in open(yourfile).read() if c in special_chars]
counted_chars = Counter(found_chars)
need not to process file contents line-by-line
to avoid nested loops, which increase complexity of your program
If you want to count character occurrences in some string, first, you loop over the entire string to construct an occurrence dict. Then, you can find any occurrence of character from the dict. This reduce complexity of the program.
When constructing occurrence dict, defaultdict would help you to initialize count values.
A refactored version of the program is as below:
special_chars = list('!"#$%&\'()*+,-./:;<=>?#[\\]^_`{|}~ ')
dict_count = defaultdict(int)
with open(filename) as f:
for c in f.read():
dict_count[c] += 1
for c in special_chars:
print('{0};{1}'.format(c, dict_count[c]))
ref. defaultdict Examples: https://docs.python.org/3.4/library/collections.html#defaultdict-examples
I did something like this where you do not need to use the counter library. I used it to count all the special char but you can adapt to put the count in a dict.
import re
def countSpecial(passwd):
specialcount = 0
for special in special_chars:
lenght = 0
#print special
lenght = len(re.findall(r'(\%s)' %special , passwd))
if lenght > 0:
#print lenght,special
specialcount = lenght + specialcount
return specialcount
I need a bit of help with this assignment (first time posting on SE so please excuse my lack of posting etiquette if any)
So for this code I had to write a spell checker. Basically what it is supposed to do is:
1.) Check through two lists (One is a dictionary, where we get all the correctly spelled words, the other is the user input list which should have an incorrectly spelled word or two)
2.) suggest a correct word in place of the misspelled word (example would be if I spelled heloo, the spell checker would say i spelled that wrong and would suggest the word is hello, help, etc.)
My biggest problem right now is at line 19, I am getting the list indices must be integers problem.
Any help is appreciated, and help with finishing this would also be much appreciated! I feel like outside of the syntax more could be improved upon. Thanks.
here is the code, it is not completely finished
import re
def words_from_file(filename):
try:
f = open(filename, "r")
words = re.split(r"[,.;:?\s]+", f.read())
f.close()
return [word for word in words if word]
except IOError:
print("Error opening %s for reading. Quitting" % (filename))
exit()
user_word = words_from_file('user_word.txt')
suggestion = words_from_file('big_word_list.txt')
sug_list = []
for a in user_word:
if user_word[a] not in suggestion:
print ("Spelling error: %s"%(user_word[a]))
for i in suggestion:
for j in suggestion[i]:
if len(suggestion[i][j]) == len(user_word[a]-2):
count = 0
similarities = len(user_word[a])
for k in suggestion[i][j]:
if suggestion[i][j][k] in suggestion:
count+=1
if count >= similarities:
sug_list.append(suggestion[i][j])
Change:
for a in user_word:
if user_word[a] not in suggestion:
Into:
for a in user_word:
if a not in suggestion:
because all items in user_word list will be iterated using the a variable. The a will in each iteration contain a nonempty string obtained from the line split. You can only use numerical index with a list type. Originally you've used a string in place of numeric index which causes the error message.
List can slice using integers not str
Change
if user_word[a] not in suggestion: #to==> if a not in suggestion:
for j in suggestion[i]: #to==> for j in i
for k in suggestion[i][j]: #to==> for k in j
Also many errors slice errors like suggestion[i][j][k] etc
So generally
for i in [1,2,3]:
print(i) # gives 1,2,3.No need of [1,2,3][i]
Also, you can use range(len)
for a in range(len(user_word)):
if user_word[a] not in suggestion: