<commit_before>
import os
import functools


def walk(src, d=None, f=print):
    """
        Recursively walks a list of files/directories different
        callback functions depending if the item is a file
        or a directory.
    """
    if isinstance(src, str):
        src = [src]

    for s in src:

        if os.path.isdir(s):
            _walk(s, d, f)
        elif f and os.path.isfile(s):
            f(s)


def _walk(s, d=None, f=print):
    """
        Recursively walks a directory and applies different
        callback functions depending if the item is a file
        or a directory.
    """
    if d is None:
        d = functools.partial(walk, d=d, f=f)

    for e in sorted(os.listdir(s)):
        path = os.path.join(s, e)

        if d and os.path.isdir(path):
            d(path)
        elif f and os.path.isfile(path):
            f(path)


def makedirs(*dirs):
    """
        Creates all directories given by `dirs` as well as their parents.
    """

    for d in dirs:
        if not os.path.exists(d):
            os.makedirs(d)


def size(*dirs):
    """
            Computes the size of a list of directories.
    """
    # http://stackoverflow.com/a/1392549/1582182
    total_size = 0

    for d in dirs:
        for dirpath, dirnames, filenames in os.walk(d):
            for f in filenames:
                fp = os.path.join(dirpath, f)
                total_size += os.path.getsize(fp)

    return total_size


class cd (object):

    """
        http://stackoverflow.com/a/13197763/1582182
        Context manager for changing the current working directory
    """

    def __init__(self, cwd):
        self.cwd = cwd

    def __enter__(self):
        self.old = os.getcwd()
        os.chdir(self.cwd)

    def __exit__(self, etype, value, traceback):
        os.chdir(self.old)

def directories(path):
    return filter( os.path.isdir , map( lambda x : os.path.join( path , x ) , os.listdir(path) ) )<commit_msg>:rocket: perf(lib.dir.directories): Use os.scandir instead of os.listdir.<commit_after>
import os
import functools


def walk(src, d=None, f=print):
    """
        Recursively walks a list of files/directories different
        callback functions depending if the item is a file
        or a directory.
    """
    if isinstance(src, str):
        src = [src]

    for s in src:

        if os.path.isdir(s):
            _walk(s, d, f)
        elif f and os.path.isfile(s):
            f(s)


def _walk(s, d=None, f=print):
    """
        Recursively walks a directory and applies different
        callback functions depending if the item is a file
        or a directory.
    """
    if d is None:
        d = functools.partial(walk, d=d, f=f)

    for e in sorted(os.listdir(s)):
        path = os.path.join(s, e)

        if d and os.path.isdir(path):
            d(path)
        elif f and os.path.isfile(path):
            f(path)


def makedirs(*dirs):
    """
        Creates all directories given by `dirs` as well as their parents.
    """

    for d in dirs:
        if not os.path.exists(d):
            os.makedirs(d)


def size(*dirs):
    """
            Computes the size of a list of directories.
    """
    # http://stackoverflow.com/a/1392549/1582182
    total_size = 0

    for d in dirs:
        for dirpath, dirnames, filenames in os.walk(d):
            for f in filenames:
                fp = os.path.join(dirpath, f)
                total_size += os.path.getsize(fp)

    return total_size


class cd (object):

    """
        http://stackoverflow.com/a/13197763/1582182
        Context manager for changing the current working directory
    """

    def __init__(self, cwd):
        self.cwd = cwd

    def __enter__(self):
        self.old = os.getcwd()
        os.chdir(self.cwd)

    def __exit__(self, etype, value, traceback):
        os.chdir(self.old)

def directories(path):
    with os.scandir(path) as entries:
        return map(lambda x: os.path.join(path, x.name), filter(lambda x: x.is_dir(), entries))
{'fraction_non_alphanumeric': 0.11202800700175043, 'fraction_numerical': 0.015003750937734433, 'mean_word_length': 1.9498525073746313, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '441601', 'n_tokens_mistral': 1372, 'n_tokens_neox': 1295, 'n_words': 389}