ওএস.ওয়াকের ডিরেক্টরি বাদে


147

আমি একটি স্ক্রিপ্ট লিখছি যা ডিরেক্টরি ট্রিতে নেমে আসে (os.walk () ব্যবহার করে) এবং তারপরে একটি নির্দিষ্ট ফাইলের এক্সটেনশনের সাথে মিলিয়ে প্রতিটি ফাইল পরিদর্শন করে। তবে যেহেতু আমার সরঞ্জামটি যে ডিরেক্টরিতে ব্যবহার করা হবে তার কয়েকটি ডিরেক্টরিতে এমন উপ ডিরেক্টরিও রয়েছে যা ঘুরেফিরে প্রচুর অকেজো (এই স্ক্রিপ্টের উদ্দেশ্যে) স্টাফ রাখে, আমি অনুভব করেছি যে আমি ব্যবহারকারীকে নির্দিষ্ট করার জন্য একটি বিকল্প যুক্ত করব ট্র্যাভারসাল থেকে বাদ দেওয়ার জন্য ডিরেক্টরিগুলির একটি তালিকা।

এটি ওএসওয়াক () দিয়ে যথেষ্ট সহজ। সর্বোপরি, আমি সিদ্ধান্ত নিতে পারি যে আমি আসলে ওএসওয়াক () দ্বারা উত্পাদিত সম্পর্কিত ফাইল / ডায়ারগুলি দেখতে যেতে পারি বা কেবল সেগুলি এড়িয়ে যেতে চাই। সমস্যাটি হ'ল যদি আমার কাছে উদাহরণস্বরূপ ডিরেক্টরি ডিরেক্টরি থাকে তবে:

root--
     |
     --- dirA
     |
     --- dirB
     |
     --- uselessStuff --
                       |
                       --- moreJunk
                       |
                       --- yetMoreJunk

এবং আমি অকেজো স্টাফ এবং তার সমস্ত শিশুদের বাদ দিতে চাই, ওস.ওয়াক () এখনও অব্যর্থ স্টাফের সমস্ত (সম্ভাব্য কয়েক হাজার) উপ ডিরেক্টরিতে প্রবেশ করবে , যা বলা বাহুল্য, জিনিসগুলি অনেকটা ধীর করে দেয়। একটি আদর্শ বিশ্বে আমি ওএসওয়াক () কে বলতে পারি যে অকেজো স্টাফের আর কোনও বাচ্চা জন্ম দেওয়ার ঝামেলা না করা , তবে আমার জ্ঞানের কাছে এটি করার কোনও উপায় নেই (আছে?)।

কারো কি কোন ধারণা আছে? হতে পারে একটি তৃতীয় পক্ষের লাইব্রেরি আছে যা এরকম কিছু সরবরাহ করে?

উত্তর:


242

পরিবর্তন dirs ইন-জায়গা আলুবোখারা পাবেন (পরবর্তী) ফাইল ও ডিরেক্টরিগুলি পরিদর্শন os.walk:

# exclude = set([...])
for root, dirs, files in os.walk(top, topdown=True):
    dirs[:] = [d for d in dirs if d not in exclude]

সহায়তা থেকে (ওএসওয়াক):

টপডাউনটি সত্য হলে, কলার ডায়ারনেম তালিকাটি জায়গায় স্থান পরিবর্তন করতে পারে (যেমন, ডেল বা স্লাইস অ্যাসাইনমেন্টের মাধ্যমে), এবং হাঁটা কেবল কেবল সেই সাব-ডিরেক্টরিতে পুনরাবৃত্তি করবে যার নামগুলি ডায়ারনেমে থাকে; এটি অনুসন্ধানে ছাঁটাই করতে ব্যবহার করা যেতে পারে ...


31
কেন dirs[:] =?
বেন

56
@ বেন: জায়গায় জায়গায়dirs[:] = value পরিবর্তন dirs করে । এটি dirsধারক পরিবর্তন না করে তালিকার বিষয়বস্তুগুলিকে পরিবর্তন করে। help(os.walk)উল্লিখিত হিসাবে , আপনি যদি os.walkসাব-ডিরেক্টরিগুলি অনুসরণ করে তার উপর প্রভাব ফেলতে চান তবে এটি প্রয়োজন । ( আসল পরিবর্তন না করে কেবল পরিবর্তনটিকে নতুন তালিকায় dirs = valueপুনরায় সাইন ইন (বা "বাঁধাই") দেয় ))dirsdirs
আনটবু

6
আপনি এটিও ব্যবহার করতে পারেন filter():dirs[:] = list(filter(lambda x: not x in exclude, dirs))
নিউক্লিয়ারপিওন

2
@ পি014 কে: আপনি নিজের জেনারেটর ফাংশন লিখতে পারেন যা কল করে os.walkএবং ফল দেয় যা থেকে root, dirs, filesবাদ .git(বা অন্য কিছু যা ইচ্ছা) বাদ দিয়ে dirs
আনতুবু

3
@ ইউন্টবু আপনাকে কেবল তা জানাতে যে একটি ক্ষেত্রে, এই অপ্টিমাইজেশানটি ট্র্যাভার্সাল সময়কে 100 সেকেন্ডের থেকে প্রায় 2 সেকেন্ডে কমিয়েছে। এটাকেই আমি সার্থক অপ্টিমাইজেশন বলি। : ডি
এন্ট্রিড

7

... @ আনুতবুর দুর্দান্ত উত্তরের একটি বিকল্প ফর্ম যা আরও কিছুটা সরাসরি পড়তে পারে, এই উদ্দেশ্যটি প্রদত্ত যে ও (এন ** 2) বনাম ও (এন) সময় ব্যয়ে ডিরেক্টরিগুলি বাদ দেওয়া ।

( list(dirs)সঠিক সম্পাদনের জন্য ডায়ার তালিকার একটি অনুলিপি তৈরি করা প্রয়োজন)

# exclude = set([...])
for root, dirs, files in os.walk(top, topdown=True):
    [dirs.remove(d) for d in list(dirs) if d in exclude]

5
কিছু মেমরির দামে যদি আপনি আরও সরাসরি হতে চান তবে আপনি আরও ভাল লিখতে চাই dirs[:] = set(dirs) - exclude। কমপক্ষে এটি এখনও \ $ O (n) $ $ এবং আপনি কেবল এর পার্শ্ব প্রতিক্রিয়াগুলির জন্য কোনও বোধগম্যতা তৈরি করেন না ...
301_মোভড_পরেমেটলি

3
এটি সত্যিই খারাপ না তবে আমার মতে অজস্র পাইথন নয়।
টর্স্টেন ব্রোঞ্জার

for d in list(dirs)কিছুটা বিজোড় dirsইতিমধ্যে একটি তালিকা। এবং আপনার যা আছে তা আসলে কোনও তালিকা বোধগম্য নয়। dirs.remove(d)কিছু ফেরত দেয় না, সুতরাং আপনি Noneগুলি পূর্ণ তালিকা সহ শেষ । আমি @ টর্স্টেনের সাথে একমত
সিএনহেনের
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.