Skip to main content
Code Review

Return to Answer

replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

As @alexwlchan @alexwlchan gave a nice answer, I won't restate what they put.

As @alexwlchan gave a nice answer, I won't restate what they put.

As @alexwlchan gave a nice answer, I won't restate what they put.

Source Link
Peilonrayz
  • 44.4k
  • 7
  • 80
  • 157

As @alexwlchan gave a nice answer, I won't restate what they put.

Instead what are the main things that your code does?

  1. Get user input, changes it it list of numbers. (While loop)
  2. Change the numbers to distinct ip addresses after being filtered to the range \1ドル < x < 70\$.
  3. Write to a file.

I'm skipping (1), for now, but (2) and (3) are perfect for Python.


You used list comprehensions in your question, you used them as a means to filter a list. However you can do both your unique and range filter in one comprehension.

[i for i in [...] if 0 < i < 70 and not (i in seen or seen_add(i))]

However you can also do what is know as map. Where you change one item to another item. For example you add ten to i and make it the last term in an ip address. Or more simply put:

['192.168.0.' + str(i + 10) for i in [...]]

however rather than doing this as two comprehensions you can just do it as one.

ips = (
 '192.168.0.' + str(i + 10)
 for i in [...]
 if 0 < i < 70 and not (i in seen or seen_add(i))
)

Alex has already gone over (3), but to re-state you want to use with. You can then consume the ips by joining them together and save them in a file.

with open('hosts.txt', 'w') as f:
 f.write('\n'.join(ips))

I kept (1) till last, as I don't think the way you have to enter data is too nice. If we were in an alternate world where Python didn't have range, first, people would hate the language, but we would build arrays the way you are.

my_list = [1, 2, 3, 4, 5, 6]

This would be a horrible world. Instead you could get the user to input a range. The below could be a nice notation to do this.

> 1..4
1, 2, 3
> 1..4, 5
1, 2, 3, 5
> 1..4, 6..8
1, 2, 3, 6, 7
# But we want to have steps!
> 1..7'2
1, 3, 5

This is actually quite easy to implement. If you think of 1..7'2 as range(1, 7, 2). All you would need to do is match the pattern \d..\d'\d. This is also fairly easy with regex.

import re
def get_input():
 regex = "(\d+)(?:\.\.(\d+)(?:\'(\d*))?)?"
 for match in re.findall(regex, input("> ")):
 match = [int(i) for i in match if i]
 if len(match) == 1:
 yield match[0]
 else:
 for j in range(*match):
 yield j

If you join this all together it would be used like:

$ python hosts.py
> 1..60'2
$ head -3 hosts.tex
192.168.0.11
192.168.0.13
192.168.0.15

If you however still want to use the while loop, then you would need it to return an array of numbers, as int's not strings.


It's also recommended to upgrade to Python3. Arch Linux has changed to Python3 being the main Python, so it makes even more sense to use Python3 rather than Python2.

lang-py

AltStyle によって変換されたページ (->オリジナル) /