1
\$\begingroup\$

The purpose is just to create a dictionary with a path name, along with the file's SHA-256 hash.

I'm very new to Python, and have a feeling that there's a much better way to implement the following code. It works, I'd just like to clean it up a bit. fnamelst = [r'C:\file1.txt', r'C:\file2.txt']

[fname.replace('\\', '\\\\') for fname in fnamelst]

diction = [{fname: hashlib.sha256(open(fname, 'rb').read()).digest()} for fname in fnamelst]

for iter in range(0,len(fnamelst)):
    dic2 = {fnamelst[iter]: hashlib.sha256(open(fnamelst[iter], 'rb').read()).digest()}
\$\endgroup\$

migrated from stackoverflow.com Jun 3 '13 at 14:24

This question came from our site for professional and enthusiast programmers.

  • 1
    \$\begingroup\$ Why are you replacing slashes?? \$\endgroup\$ – kirelagin Jun 3 '13 at 14:20
  • 1
    \$\begingroup\$ Well, you've created the dictionary twice. What's the question? \$\endgroup\$ – kirelagin Jun 3 '13 at 14:20
  • 2
    \$\begingroup\$ Note that the for loop will overwrite dic2 each time, instead of extending it. \$\endgroup\$ – tobias_k Jun 3 '13 at 14:24
4
\$\begingroup\$

In your code, you show two ways to create your dictionary, but both are somewhat flawed:

  • diction will be a list of dictionaries, each holding just one entry
  • dic2 will get overwritten in each iteration of the loop, and will finally hold only one dictionary, again with only one element.

Instead, try this:

diction = dict([ (fname, hashlib.sha256(open(fname, 'rb').read()).digest())
                 for fname in fnamelst ])

Or shorter, for Python 2.7 or later:

diction = { fname: hashlib.sha256(open(fname, 'rb').read()).digest()
                 for fname in fnamelst }

The first one uses a list comprehension to create a list of key-value tuples, and then uses the dict function to create a single dictionary from that list. The second one does the same, using a dict comprehension.

\$\endgroup\$
2
\$\begingroup\$

In python, for iter in range(0,len(container)): is pretty much always a bad pattern.

Here, you can rewrite :

for f in fnamelst:
    dic2 = {f: hashlib.sha256(open(f, 'rb').read()).digest()}

As @tobias_k pointed out, this doesn't do much at the moment as dict2 gets overriden. In Python 2.7+ or 3, you can just use the dict comprehension directly.

\$\endgroup\$
1
\$\begingroup\$

You have some confusion about using backslahses in Python strings.

r'C:\file1.txt' is a raw string and the backslash is a backslash. r in front denotes raw.

'C:\\file1.txt' is the same string written as a normal string literal. Now the backslash has to be written as \\, because otherwise \f would be interpreted as a control character \x0c.

Doubling the backslash using replace serves no purpose here. Moreover, as tobias_k points out, the line with the replace has no effect at all because the resulting modified list is not assigned to a variable.

\$\endgroup\$
  • 1
    \$\begingroup\$ Moreover, the line with the replace has no effect at all, as the strings in the list are immutable, and the new list is not assigned to a variable. \$\endgroup\$ – tobias_k Jun 4 '13 at 7:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.