পাইথনে শীর্ষ স্তরের ডিরেক্টরি কীভাবে তালিকাবদ্ধ করতে হয়?


132

আমি কিছু ফোল্ডারের মধ্যে কেবল ডিরেক্টরিগুলি তালিকা করতে সক্ষম হতে চাই। এর অর্থ আমি ফাইলের তালিকাভুক্ত চাই না, বা অতিরিক্ত সাব-ফোল্ডারও চাই না।

একটি উদাহরণ সাহায্য করে কিনা তা দেখুন। বর্তমান ডিরেক্টরিতে আমাদের রয়েছে:

>>> os.listdir(os.getcwd())
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'mod_p
ython-wininst.log', 'NEWS.txt', 'pymssql-wininst.log', 'python.exe', 'pythonw.ex
e', 'README.txt', 'Removemod_python.exe', 'Removepymssql.exe', 'Scripts', 'tcl',
 'Tools', 'w9xpopen.exe']

তবে আমি ফাইলের নাম তালিকাভুক্ত করতে চাই না। আমি উপ-ফোল্ডার যেমন \ Lib \ অভিশাপ চাই না। মূলত আমি যা চাই তা নিম্নলিখিতগুলির সাথে কাজ করে:

>>> for root, dirnames, filenames in os.walk('.'):
...     print dirnames
...     break
...
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'Scripts', 'tcl', 'Tools']

তবে, আমি ভাবছি যে একই ফলাফলগুলি অর্জনের সহজ উপায় আছে কিনা। আমি এই ধারণাটি পেয়েছি যে ওএস.ওয়াকটি কেবলমাত্র শীর্ষ স্তরটি ফিরিয়ে আনার জন্য অক্ষম / অত্যধিক।

উত্তর:


125

Os.path.isdir () ব্যবহার করে ফলাফল ফিল্টার করুন (এবং আসল পথ পেতে os.path.join () ব্যবহার করুন):

>>> [ name for name in os.listdir(thedir) if os.path.isdir(os.path.join(thedir, name)) ]
['ctypes', 'distutils', 'encodings', 'lib-tk', 'config', 'idlelib', 'xml', 'bsddb', 'hotshot', 'logging', 'doc', 'test', 'compiler', 'curses', 'site-packages', 'email', 'sqlite3', 'lib-dynload', 'wsgiref', 'plat-linux2', 'plat-mac']

17
এটি খুবই সহজ os.walk বনাম প্রক্রিয়াকরণের অনেক সময় লাগবে () পরবর্তী () [1]।
Phyo Arkar Lwin

203

os.walk

আইটেম ফাংশন os.walkসহ ব্যবহার করুন next:

next(os.walk('.'))[1]

জন্য পাইথন <= 2.5 ব্যবহার করুন:

os.walk('.').next()[1]

এটি কীভাবে কাজ করে

os.walkএকটি জেনারেটর এবং কলিং next3-টিউপল আকারে প্রথম ফলাফল পাবেন (dirpath, dirnames, ফাইলের নাম)। সুতরাং [1]সূচকটি কেবল এই dirnamesটিপল থেকে ফেরত দেয় ।


14
এ সম্পর্কে আরও কিছুটা বিবরণ হ'ল এটি একটি জেনারেটর, আপনি এটি না বললে এটি অন্য ডায়ারগুলি হাঁটবে না। সুতরাং .xt () [1] সমস্ত লাইনের বোধগম্যতা এক লাইনে করে does আমি সম্ভবত ভালো কিছু করতে চাই DIRNAMES=1এবং তারপর next()[DIRNAMES]সহজে ভবিষ্যৎ কোড রক্ষণাবেক্ষণকারীকে জন্য বুঝতে হবে।
বোটকোডার

3
+1 আশ্চর্যজনক সমাধান। ব্রাউজ করার জন্য একটি ডিরেক্টরি নির্দিষ্ট করতে, ব্যবহার করুন:os.walk( os.path.join(mypath,'.')).next()[1]
ড্যানিয়েল রেইস

42
পাইথন ভি 3 এর জন্য: পরের (ওস.ওয়াক ('।')) [1]
আন্দ্রে সোয়রেস

যদি আপনি আরও কিছু করতে যাচ্ছেন তবে পাঠ্য প্রক্রিয়াজাতকরণ; অর্থাত্ প্রকৃত ফোল্ডারগুলিতে প্রক্রিয়াজাতকরণের পরে সম্পূর্ণ পাথের প্রয়োজন হতে পারে:sorted( [os.path.join(os.getcwd(), item) for item in os.walk(os.curdir).next()[1]] )
দেবপ্লেয়ার

52

ডিরেক্টরিগুলি সনাক্ত করতে os.path.isdir ব্যবহার করে তালিকাটি ফিল্টার করুন।

filter(os.path.isdir, os.listdir(os.getcwd()))

5
আমি মনে করি এটি এগুলির যে কোনও উত্তরে পাঠযোগ্যতা এবং সংক্ষিপ্ততার সর্বোত্তম সংমিশ্রণ।
ভার্জেনজট

20
এটি কাজ করে না। আমার অনুমান যে os.listdirকোনও ফাইল / ফোল্ডারের নাম ফেরত দেয় os.path.isdir, তবে শেষেরটির জন্য একটি পুরো পথ প্রয়োজন।
ড্যানিয়েল রেইস

3
ফিল্টার timeit(os.walk(os.getcwd()).next()[1]) 1000 loops, best of 3: 734 µs per loop timeit(filter(os.path.isdir, os.listdir(os.getcwd()))) 1000 loops, best of 3: 477 µs per loop
ওএসওয়াকের

14
directories=[d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]

4
এটি ফিল্টার করে ছোট করা যেতে পারে (os.path.isdir, os.listdir (os.getcwd ())
জন মিলিকিন

3
ফিল্টার বা একটি তালিকা বোঝার দ্রুত হয় কিনা সে সম্পর্কে কারও কাছে কোনও তথ্য আছে? অন্যথায় এটি কেবল একটি বিষয়গত যুক্তি। অবশ্যই এটি ধরে নিয়েছে সিডব্লিউডে 10 মিলিয়ন ডিরেক্টরি রয়েছে এবং কার্য সম্পাদন একটি সমস্যা issue
মার্ক রডি

12

মনে রাখবেন যে, না করে বরং os.listdir(os.getcwd())এটি করা ভাল os.listdir(os.path.curdir)। একটি কম ফাংশন কল, এবং এটি পোর্টেবল হিসাবে।

সুতরাং, উত্তরটি সম্পূর্ণ করতে, ফোল্ডারে ডিরেক্টরিগুলির একটি তালিকা পেতে:

def listdirs(folder):
    return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]

আপনি যদি পুরো পথের নাম পছন্দ করেন তবে এই ফাংশনটি ব্যবহার করুন:

def listdirs(folder):
    return [
        d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
        if os.path.isdir(d)
    ]

9

এটি খুব কার্যকর বলে মনে হচ্ছে (কমপক্ষে লিনাক্সে):

import glob, os
glob.glob('*' + os.path.sep)

1
+1 এর জন্য glob। এটি আপনাকে প্রচুর কোড বাঁচাতে পারে, বিশেষত পুনরাবৃত্তিগুলি, এবং ইউনিক্স টার্মিনাল ব্যবহারের সাথে অনেকটা অনুরূপ ( ls)
জেরার্ড

5
Glob.glob ('*' + os.path.sep) এর চেয়ে আপনি লিখতে চাইতে পারেন [গ্লোব.glob ("*") এর জন্য dir লিখতে যদি os.path.isdir (dir)]
ইমন এমআর এম

8

কেবল যুক্ত করার জন্য যে os.listdir () ব্যবহার করে "খুব সাধারণ বনাম খুব প্রচুর প্রসেসিং লাগে না ..ওয়ালক ()। পরবর্তী () [1]" । এটি কারণ os.walk () অভ্যন্তরীণভাবে os.listdir () ব্যবহার করে। আসলে যদি আপনি তাদের একসাথে পরীক্ষা করেন:

>>>> import timeit
>>>> timeit.timeit("os.walk('.').next()[1]", "import os", number=10000)
1.1215229034423828
>>>> timeit.timeit("[ name for name in os.listdir('.') if os.path.isdir(os.path.join('.', name)) ]", "import os", number=10000)
1.0592019557952881

Os.listdir () এর ফিল্টারিং খুব সামান্য দ্রুত।


2
পাইথন 3.5 আসছে ডিরেক্টরির বিষয়বস্তু পাবার একটি দ্রুত উপায় হল: python.org/dev/peps/pep-0471
Foz

1
pep-0471 - scandirপ্যাকেজটি পাইথন ২. 2. এর পরে পাইপিআই-তে ইনস্টলযোগ্য প্যাকেজ হিসাবে আনন্দের সাথে উপলব্ধ। এটি এর জন্য প্রতিস্থাপন প্রস্তাব os.walkএবং os.listdirএটি অনেক দ্রুত।
ফোজ

6

এটি ব্যবহার করা খুব সহজ এবং মার্জিত উপায়:

 import os
 dir_list = os.walk('.').next()[1]
 print dir_list

এই স্ক্রিপ্টটি একই ফোল্ডারে চালান যার জন্য আপনি ফোল্ডারের নাম চান t এটি আপনাকে অবিলম্বে ফোল্ডারগুলির নাম দেবে (এটিও ফোল্ডারের পুরো পথ ছাড়াই)।


6

তালিকা অনুধাবন ব্যবহার করে,

[a for a in os.listdir() if os.path.isdir(a)]

আমি মনে করি এটি সহজতম উপায়


2

এখানে নবাগত হয়ে আমি সরাসরি সরাসরি মন্তব্য করতে পারি না তবে এখানে একটি ছোট সংশোধন আমি answer এর উত্তরের নীচের অংশে যুক্ত করতে চাই :

আপনি যদি পুরো পথের নাম পছন্দ করেন তবে এই ফাংশনটি ব্যবহার করুন:

def listdirs(folder):  
  return [
    d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
    if os.path.isdir(d)
]

অজগর এখনও যারা তাদের জন্য <2.4 : অভ্যন্তরীণ কাঠামোটি একটি টিউপলের পরিবর্তে একটি তালিকা হওয়া দরকার এবং তাই এটি পড়তে হবে:

def listdirs(folder):  
  return [
    d for d in [os.path.join(folder, d1) for d1 in os.listdir(folder)]
    if os.path.isdir(d)
  ]

অন্যথায় এক একটি সিনট্যাক্স ত্রুটি পায়।


আমি জানি কিছুক্ষণ হয়েছে, তবে এই প্রথম উদাহরণটি আমাকে সত্যিই সাহায্য করেছিল।
ইনবার রোজ

1
আপনি একটি বাক্য গঠন ত্রুটি পেয়েছেন কারণ আপনার সংস্করণ জেনারেটর এক্সপ্রেশন সমর্থন করে না। এগুলি পাইথন ২.৪-এ প্রবর্তিত হয়েছিল যদিও পাইথন ২.০ থেকে তালিকা উপলব্ধি উপলব্ধ।
আগত


1

পুরো পথের নামের তালিকার জন্য আমি এখানে অন্যান্য সমাধানগুলির তুলনায় এই সংস্করণটিকে পছন্দ করি :

def listdirs(dir):
    return [os.path.join(os.path.join(dir, x)) for x in os.listdir(dir) 
        if os.path.isdir(os.path.join(dir, x))]

1
scanDir = "abc"
directories = [d for d in os.listdir(scanDir) if os.path.isdir(os.path.join(os.path.abspath(scanDir), d))]

0

একটি নিরাপদ বিকল্প যা কোনও ডিরেক্টরি না থাকলে ব্যর্থ হয় না।

def listdirs(folder):
    if os.path.exists(folder):
         return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]
    else:
         return []


0

পাইথন ৩.৪ স্ট্যান্ডার্ড লাইব্রেরিতে মডিউলটি প্রবর্তন করেছেpathlib , যা ফাইল সিস্টেমের পাথগুলি পরিচালনা করতে একটি অবজেক্ট ওরিয়েন্টেড পদ্ধতির সরবরাহ করে:

from pathlib import Path

p = Path('./')
[f for f in p.iterdir() if f.is_dir()]

-1
-- This will exclude files and traverse through 1 level of sub folders in the root

def list_files(dir):
    List = []
    filterstr = ' '
    for root, dirs, files in os.walk(dir, topdown = True):
        #r.append(root)
        if (root == dir):
            pass
        elif filterstr in root:
            #filterstr = ' '
            pass
        else:
            filterstr = root
            #print(root)
            for name in files:
                print(root)
                print(dirs)
                List.append(os.path.join(root,name))
            #print(os.path.join(root,name),"\n")
                print(List,"\n")

    return List
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.