Repository: pandas-dev/pandas
File: pandas/core/internals/managers.py (Python)

Code before:
            blknos = algos.take_nd(
                self.blknos, slobj, fill_value=-1, allow_fill=allow_fill
            )
            blklocs = algos.take_nd(
                self.blklocs, slobj, fill_value=-1, allow_fill=allow_fill
            )

        # When filling blknos, make sure blknos is updated before appending to
        # blocks list, that way new blkno is exactly len(blocks).
        group = not only_slice
        for blkno, mgr_locs in libinternals.get_blkno_placements(blknos, group=group):
            if blkno == -1:
                # If we've got here, fill_value was not lib.no_default
                # GH#63993: Use _make_na_blocks to handle 1D-only extension dtypes properly
                dtype, _ = infer_dtype_from_scalar(fill_value)
                if is_1d_only_ea_dtype(dtype) and len(mgr_locs) > 1:
                    # Create separate blocks for each column to maintain consistent dtype
                    for block in self._make_na_blocks(
                        placement=mgr_locs,
                        fill_value=fill_value,
                        use_na_proxy=use_na_proxy,
                    ):
                        yield block
                else:
                    # Use original single block approach
                    yield self._make_na_block(
                        placement=mgr_locs,
                        fill_value=fill_value,
                        use_na_proxy=use_na_proxy,
                    )
            else:
                blk = self.blocks[blkno]

                # Otherwise, slicing along items axis is necessary.
                if not blk._can_consolidate and not blk._validate_ndim:
                    # i.e. we dont go through here for DatetimeTZBlock
                    # A non-consolidatable block, it's easy, because there's
                    # only one item and each mgr loc is a copy of that single
                    # item.
                    deep = False
                    for mgr_loc in mgr_locs:
                        newblk = blk.copy(deep=deep)
                        newblk.mgr_locs = BlockPlacement(slice(mgr_loc, mgr_loc + 1))
                        yield newblk

                else:
                    # GH#32779 to avoid the performance penalty of copying,
                    #  we may try to only slice
                    taker = blklocs[mgr_locs.indexer]
                    max_len = max(len(mgr_locs), taker.max() + 1)
                    taker = lib.maybe_indices_to_slice(taker, max_len)

Review comment (refactor):
I think you could try to simplify the change below by iterating over the mgr_locs, and in the loop above also call `_make_na_block`, so then we should not need the new `_make_na_blocks` method that returns multiple blocks

Code after:
            blknos = algos.take_nd(
                self.blknos, slobj, fill_value=-1, allow_fill=allow_fill
            )
            blklocs = algos.take_nd(
                self.blklocs, slobj, fill_value=-1, allow_fill=allow_fill
            )

        # When filling blknos, make sure blknos is updated before appending to
        # blocks list, that way new blkno is exactly len(blocks).
        group = not only_slice
        for blkno, mgr_locs in libinternals.get_blkno_placements(blknos, group=group):
            if blkno == -1:
                # If we've got here, fill_value was not lib.no_default

                dtype, _ = infer_dtype_from_scalar(fill_value)
                if is_1d_only_ea_dtype(dtype) and len(mgr_locs) > 1:
                    # Handle 1D-only extension dtypes by creating separate blocks
                    # (GH#63993)
                    placements = [BlockPlacement(col_idx) for col_idx in mgr_locs]
                else:
                    placements = [mgr_locs]

                for placement in placements:
                    yield self._make_na_block(
                        placement=placement,
                        fill_value=fill_value,
                        use_na_proxy=use_na_proxy,
                    )
            else:
                blk = self.blocks[blkno]

                # Otherwise, slicing along items axis is necessary.
                if not blk._can_consolidate and not blk._validate_ndim:
                    # i.e. we dont go through here for DatetimeTZBlock
                    # A non-consolidatable block, it's easy, because there's
                    # only one item and each mgr loc is a copy of that single
                    # item.
                    deep = False
                    for mgr_loc in mgr_locs:
                        newblk = blk.copy(deep=deep)
                        newblk.mgr_locs = BlockPlacement(slice(mgr_loc, mgr_loc + 1))
                        yield newblk

                else:
                    # GH#32779 to avoid the performance penalty of copying,
                    #  we may try to only slice
                    taker = blklocs[mgr_locs.indexer]
                    max_len = max(len(mgr_locs), taker.max() + 1)
                    taker = lib.maybe_indices_to_slice(taker, max_len)

                    if isinstance(taker, slice):