> let me know if someone has tried to implement (grep and PIPE) shell commands in python `lspci | grep Q | grep "$isp_str1" | grep "$isp_str2" | cut -c1-7'
Welcome!
While it's technically possible to do exactly that in Python (using
subprocess as you describe), there's usually a more efficient and
cleaner method of achieving the same goal. With a port such as you
describe, it's probably best to go right back to the conceptual level
and work out what exactly you're trying to do, and then look at
implementing that in Python. You'll end up with much cleaner code at
the end of it.
For an initial guess, I would say that you'll use subprocess to invoke
lspci, but then everything else will be done in Python directly.
import subprocess
[ l.partition(' ')[0] # or l[:7], if you want to copy it verbatim
for l in subprocess.check_output(['lspci']).splitlines()
if 'Q' in l and isp_str1 in l and isp_str2 in l
]
You can also just paste the whole pipeline with the shell=True
parameter. That's not recommended though, and it's hard to correctly
quote strings.
> > I was trying porting from bash shell to python.
> > let me know if someone has tried to implement (grep and PIPE) shell commands in python `lspci | grep Q | grep "$isp_str1" | grep "$isp_str2" | cut -c1-7'
> Welcome!
> While it's technically possible to do exactly that in Python (using
> subprocess as you describe), there's usually a more efficient and
> cleaner method of achieving the same goal. With a port such as you
> describe, it's probably best to go right back to the conceptual level
> and work out what exactly you're trying to do, and then look at
> implementing that in Python. You'll end up with much cleaner code at
> the end of it.
> For an initial guess, I would say that you'll use subprocess to invoke
> lspci, but then everything else will be done in Python directly.
On Mon, Jul 30, 2012 at 12:35:38PM +0200, Philipp Hagemeister wrote:
> On 07/30/2012 09:05 AM, Vikas Kumar Choudhary wrote:
> > `lspci | grep Q | grep "$isp_str1" | grep "$isp_str2" | cut -c1-7'
> The rough Python equivalent would be
> import subprocess
> [ l.partition(' ')[0] # or l[:7], if you want to copy it verbatim
> for l in subprocess.check_output(['lspci']).splitlines()
> if 'Q' in l and isp_str1 in l and isp_str2 in l
> ]
Ouch. A list comprehension spanning more than one line is bad code
pretty much every time.
But even if you can port the shell script literally I recommend a more structured approach:
import subprocess
import itertools
def parse_data(lines):
for not_empty, group in itertools.groupby(lines, key=bool):
if not_empty:
triples = (line.partition(":") for line in group)
pairs = ((left, right.strip()) for left, sep, right in triples)
yield dict(pairs)
if __name__ == "__main__":
def get(field):
return entry.get(field, "").lower()
output = subprocess.Popen(["lspci", "-vmm"], stdout=subprocess.PIPE).communicate()[0]
for entry in parse_data(output.splitlines()):
if "nvidia" in get("Vendor") and "usb" in get("Device"):
print entry["Slot"]
print entry["Device"]
print
> On Mon, Jul 30, 2012 at 12:35:38PM +0200, Philipp Hagemeister wrote:
>> import subprocess
>> [ l.partition(' ')[0] # or l[:7], if you want to copy it verbatim
>> for l in subprocess.check_output(['lspci']).splitlines()
>> if 'Q' in l and isp_str1 in l and isp_str2 in l
>> ]
> Ouch. A list comprehension spanning more than one line is bad code
> pretty much every time.
I didn't want to introduce a separate function, but as requested, here's
the function version:
def pciIds(searchWords=['Q', isp_str1, isp_str2]):
for l in subprocess.check_output(['lspci']).splitlines():
if all(sw in l for sw in searchWords):
yield l.partition(' ')[0]
You could also separate the processing, like this:
lines = subprocess.check_output(['lspci']).splitlines()
lines = [l for l in lines if 'Q' in l and isp_str1 in l and isp_str2 in l]
# Or:
lines = filter(lambda l: 'Q' in l and isp_str1 in l and isp_str2 in l,
lines)
[l.partition(' ')[0] for l in lines]
# Or:
map(lambda l: l.partition(' ')[0], lines)
But personally, I have no problem with three-line list comprehensions.
Can you elaborate why the list comprehension version is bad code?
> On Mon, Jul 30, 2012 at 9:26 PM, Barry Scott <ba...@barrys-emacs.org
> And of course you can write list comprehensions on as many lines as
> it take to make the code maintainable.
> Sigh, and I'm also not keen on multi-line list comprehensions,
> specifically because I think they tend to make less readable code. It
> also becomes a mess when you need to insert print statements to get some
> visibility into what's going on.
I tend to write long one-liners then convert them to loops the first time I need to see what's going on.
> On Mon, 30 Jul 2012 22:56:48 +0000, Dan Stromberg <drsali...@gmail.com>
> declaimed the following in gmane.comp.python.general:
>> Sigh, and I'm also not keen on multi-line list comprehensions, specifically
>> because I think they tend to make less readable code. It also becomes a
>> mess when you need to insert print statements to get some visibility into
>> what's going on.
On Tue, Jul 31, 2012 at 5:15 PM, Mark Lawrence <breamore...@yahoo.co.uk> wrote:
> On 31/07/2012 02:20, Dennis Lee Bieber wrote:
>> should be pecked to death by a dead parrot.
> Any particular species?
I'm sure that, if you're in Norway, you could find an appropriate
bird. But for those of us for whom that's not an option, I'd be
content to nail the programmer's feet to the cage and then return him
whence he came as a faulty model. Unfortunately local law enforcement
would want in on that deal.
On Tue, 31 Jul 2012 08:15:32 +0100, Mark Lawrence wrote:
> On 31/07/2012 02:20, Dennis Lee Bieber wrote:
>> On Mon, 30 Jul 2012 22:56:48 +0000, Dan Stromberg <drsali...@gmail.com>
>> declaimed the following in gmane.comp.python.general:
>>> Sigh, and I'm also not keen on multi-line list comprehensions,
>>> specifically because I think they tend to make less readable code. It
>>> also becomes a mess when you need to insert print statements to get
>>> some visibility into what's going on.